Browse Source

Merge pull request #46734 from thaJeztah/vendor_containerd_1.7.8

vendor: github.com/containerd/containerd v1.7.8
Sebastiaan van Stijn 1 năm trước cách đây
mục cha
commit
53ebecea7c
100 tập tin đã thay đổi với 14461 bổ sung338 xóa
  1. 14 11
      vendor.mod
  2. 33 24
      vendor.sum
  3. 8 8
      vendor/cloud.google.com/go/.release-please-manifest-individual.json
  4. 123 114
      vendor/cloud.google.com/go/.release-please-manifest-submodules.json
  5. 1 1
      vendor/cloud.google.com/go/.release-please-manifest.json
  6. 33 0
      vendor/cloud.google.com/go/CHANGES.md
  7. 1 1
      vendor/cloud.google.com/go/compute/internal/version.go
  8. 23 13
      vendor/cloud.google.com/go/doc.go
  9. 149 0
      vendor/cloud.google.com/go/go.work
  10. 21 0
      vendor/cloud.google.com/go/go.work.sum
  11. 21 0
      vendor/cloud.google.com/go/longrunning/CHANGES.md
  12. 5 64
      vendor/cloud.google.com/go/longrunning/autogen/doc.go
  13. 26 27
      vendor/cloud.google.com/go/longrunning/autogen/longrunningpb/operations.pb.go
  14. 18 34
      vendor/cloud.google.com/go/longrunning/autogen/operations_client.go
  15. 32 3
      vendor/cloud.google.com/go/release-please-config-yoshi-submodules.json
  16. 5 0
      vendor/github.com/containerd/containerd/Makefile
  17. 1 1
      vendor/github.com/containerd/containerd/Vagrantfile
  18. 18 0
      vendor/github.com/containerd/containerd/oci/spec.go
  19. 15 4
      vendor/github.com/containerd/containerd/pull.go
  20. 8 8
      vendor/github.com/containerd/containerd/remotes/docker/authorizer.go
  21. 7 4
      vendor/github.com/containerd/containerd/remotes/docker/pusher.go
  22. 1 1
      vendor/github.com/containerd/containerd/version/version.go
  23. 6 0
      vendor/github.com/google/s2a-go/.gitignore
  24. 93 0
      vendor/github.com/google/s2a-go/CODE_OF_CONDUCT.md
  25. 29 0
      vendor/github.com/google/s2a-go/CONTRIBUTING.md
  26. 202 0
      vendor/github.com/google/s2a-go/LICENSE.md
  27. 17 0
      vendor/github.com/google/s2a-go/README.md
  28. 167 0
      vendor/github.com/google/s2a-go/fallback/s2a_fallback.go
  29. 119 0
      vendor/github.com/google/s2a-go/internal/authinfo/authinfo.go
  30. 438 0
      vendor/github.com/google/s2a-go/internal/handshaker/handshaker.go
  31. 99 0
      vendor/github.com/google/s2a-go/internal/handshaker/service/service.go
  32. 389 0
      vendor/github.com/google/s2a-go/internal/proto/common_go_proto/common.pb.go
  33. 267 0
      vendor/github.com/google/s2a-go/internal/proto/s2a_context_go_proto/s2a_context.pb.go
  34. 1377 0
      vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a.pb.go
  35. 173 0
      vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a_grpc.pb.go
  36. 367 0
      vendor/github.com/google/s2a-go/internal/proto/v2/common_go_proto/common.pb.go
  37. 248 0
      vendor/github.com/google/s2a-go/internal/proto/v2/s2a_context_go_proto/s2a_context.pb.go
  38. 2494 0
      vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a.pb.go
  39. 159 0
      vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a_grpc.pb.go
  40. 34 0
      vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aeadcrypter.go
  41. 70 0
      vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aesgcm.go
  42. 67 0
      vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/chachapoly.go
  43. 92 0
      vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/common.go
  44. 98 0
      vendor/github.com/google/s2a-go/internal/record/internal/halfconn/ciphersuite.go
  45. 60 0
      vendor/github.com/google/s2a-go/internal/record/internal/halfconn/counter.go
  46. 59 0
      vendor/github.com/google/s2a-go/internal/record/internal/halfconn/expander.go
  47. 193 0
      vendor/github.com/google/s2a-go/internal/record/internal/halfconn/halfconn.go
  48. 757 0
      vendor/github.com/google/s2a-go/internal/record/record.go
  49. 176 0
      vendor/github.com/google/s2a-go/internal/record/ticketsender.go
  50. 70 0
      vendor/github.com/google/s2a-go/internal/tokenmanager/tokenmanager.go
  51. 1 0
      vendor/github.com/google/s2a-go/internal/v2/README.md
  52. 122 0
      vendor/github.com/google/s2a-go/internal/v2/certverifier/certverifier.go
  53. BIN
      vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_intermediate_cert.der
  54. BIN
      vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_leaf_cert.der
  55. BIN
      vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_root_cert.der
  56. BIN
      vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_intermediate_cert.der
  57. BIN
      vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_leaf_cert.der
  58. BIN
      vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_root_cert.der
  59. 186 0
      vendor/github.com/google/s2a-go/internal/v2/remotesigner/remotesigner.go
  60. BIN
      vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.der
  61. 24 0
      vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.pem
  62. 27 0
      vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_key.pem
  63. BIN
      vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.der
  64. 24 0
      vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.pem
  65. 27 0
      vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_key.pem
  66. 354 0
      vendor/github.com/google/s2a-go/internal/v2/s2av2.go
  67. 24 0
      vendor/github.com/google/s2a-go/internal/v2/testdata/client_cert.pem
  68. 27 0
      vendor/github.com/google/s2a-go/internal/v2/testdata/client_key.pem
  69. 24 0
      vendor/github.com/google/s2a-go/internal/v2/testdata/server_cert.pem
  70. 27 0
      vendor/github.com/google/s2a-go/internal/v2/testdata/server_key.pem
  71. 24 0
      vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_cert.pem
  72. 27 0
      vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_key.pem
  73. 24 0
      vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_cert.pem
  74. 27 0
      vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_key.pem
  75. 404 0
      vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/tlsconfigstore.go
  76. 412 0
      vendor/github.com/google/s2a-go/s2a.go
  77. 208 0
      vendor/github.com/google/s2a-go/s2a_options.go
  78. 79 0
      vendor/github.com/google/s2a-go/s2a_utils.go
  79. 34 0
      vendor/github.com/google/s2a-go/stream/s2a_stream.go
  80. 24 0
      vendor/github.com/google/s2a-go/testdata/client_cert.pem
  81. 27 0
      vendor/github.com/google/s2a-go/testdata/client_key.pem
  82. 24 0
      vendor/github.com/google/s2a-go/testdata/server_cert.pem
  83. 27 0
      vendor/github.com/google/s2a-go/testdata/server_key.pem
  84. 1 1
      vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json
  85. 45 0
      vendor/github.com/googleapis/gax-go/v2/CHANGES.md
  86. 14 0
      vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go
  87. 21 0
      vendor/github.com/googleapis/gax-go/v2/call_option.go
  88. 67 1
      vendor/github.com/googleapis/gax-go/v2/header.go
  89. 1 1
      vendor/github.com/googleapis/gax-go/v2/internal/version.go
  90. 10 0
      vendor/github.com/googleapis/gax-go/v2/invoke.go
  91. 98 0
      vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go
  92. 87 0
      vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
  93. 2696 0
      vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s
  94. 81 0
      vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
  95. 16 0
      vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go
  96. 86 0
      vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go
  97. 93 0
      vendor/golang.org/x/crypto/hkdf/hkdf.go
  98. 3 6
      vendor/golang.org/x/oauth2/google/default.go
  99. 1 1
      vendor/golang.org/x/oauth2/internal/oauth2.go
  100. 50 10
      vendor/golang.org/x/oauth2/internal/token.go

+ 14 - 11
vendor.mod

@@ -26,7 +26,7 @@ require (
 	github.com/cloudflare/cfssl v1.6.4
 	github.com/container-orchestrated-devices/container-device-interface v0.6.1
 	github.com/containerd/cgroups/v3 v3.0.2
-	github.com/containerd/containerd v1.7.7
+	github.com/containerd/containerd v1.7.8
 	github.com/containerd/continuity v0.4.2
 	github.com/containerd/fifo v1.1.0
 	github.com/containerd/log v0.1.0
@@ -99,23 +99,23 @@ require (
 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0
 	go.opentelemetry.io/otel/sdk v1.14.0
 	go.opentelemetry.io/otel/trace v1.14.0
-	golang.org/x/mod v0.10.0
+	golang.org/x/mod v0.11.0
 	golang.org/x/net v0.17.0
 	golang.org/x/sync v0.3.0
 	golang.org/x/sys v0.13.0
 	golang.org/x/text v0.13.0
 	golang.org/x/time v0.3.0
-	google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1
-	google.golang.org/grpc v1.56.3
+	google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98
+	google.golang.org/grpc v1.58.3
 	google.golang.org/protobuf v1.31.0
 	gotest.tools/v3 v3.5.1
 	resenje.org/singleflight v0.4.0
 )
 
 require (
-	cloud.google.com/go v0.110.0 // indirect
-	cloud.google.com/go/compute v1.19.1 // indirect
-	cloud.google.com/go/longrunning v0.4.1 // indirect
+	cloud.google.com/go v0.110.4 // indirect
+	cloud.google.com/go/compute v1.21.0 // indirect
+	cloud.google.com/go/longrunning v0.5.1 // indirect
 	github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect
 	github.com/agext/levenshtein v1.2.3 // indirect
 	github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect
@@ -155,9 +155,10 @@ require (
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
 	github.com/google/btree v1.1.2 // indirect
 	github.com/google/certificate-transparency-go v1.1.4 // indirect
+	github.com/google/s2a-go v0.1.4 // indirect
 	github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
 	github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
-	github.com/googleapis/gax-go/v2 v2.7.1 // indirect
+	github.com/googleapis/gax-go/v2 v2.11.0 // indirect
 	github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
 	github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect
 	github.com/hashicorp/errwrap v1.1.0 // indirect
@@ -204,10 +205,12 @@ require (
 	go.uber.org/multierr v1.8.0 // indirect
 	go.uber.org/zap v1.21.0 // indirect
 	golang.org/x/crypto v0.14.0 // indirect
-	golang.org/x/oauth2 v0.7.0 // indirect
-	golang.org/x/tools v0.8.0 // indirect
-	google.golang.org/api v0.114.0 // indirect
+	golang.org/x/oauth2 v0.10.0 // indirect
+	golang.org/x/tools v0.10.0 // indirect
+	google.golang.org/api v0.126.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
+	google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	k8s.io/klog/v2 v2.90.1 // indirect
 	sigs.k8s.io/yaml v1.3.0 // indirect

+ 33 - 24
vendor.sum

@@ -21,26 +21,26 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
 cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
 cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
 cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
-cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
-cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=
+cloud.google.com/go v0.110.4 h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk=
+cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
 cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
 cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
 cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
 cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
 cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
 cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY=
-cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE=
+cloud.google.com/go/compute v1.21.0 h1:JNBsyXVoOoNJtTQcnEY5uYpZIbeCTYIeDe0Xh1bySMk=
+cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
 cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
 cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
 cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
 cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
-cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k=
+cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y=
 cloud.google.com/go/logging v1.7.0 h1:CJYxlNNNNAMkHp9em/YEXcfJg+rPDg7YfwoRpMU+t5I=
 cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M=
-cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM=
-cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo=
+cloud.google.com/go/longrunning v0.5.1 h1:Fr7TXftcqTudoyRJa113hyaqlGdiBQkp0Gq7tErFDWI=
+cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc=
 cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
 cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
 cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
@@ -312,8 +312,8 @@ github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMX
 github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
 github.com/containerd/containerd v1.4.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
 github.com/containerd/containerd v1.4.1-0.20201117152358-0edc412565dc/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.7.7 h1:QOC2K4A42RQpcrZyptP6z9EJZnlHfHJUfZrAAHe15q4=
-github.com/containerd/containerd v1.7.7/go.mod h1:3c4XZv6VeT9qgf9GMTxNTMFxGJrGpI2vz1yk4ye+YY8=
+github.com/containerd/containerd v1.7.8 h1:RkwgOW3AVUT3H/dyT0W03Dc8AzlpMG65lX48KftOFSM=
+github.com/containerd/containerd v1.7.8/go.mod h1:L/Hn9qylJtUFT7cPeM0Sr3fATj+WjHwRQ0lyrYk3OPY=
 github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
 github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
 github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
@@ -448,7 +448,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
 github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8=
+github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
 github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
@@ -657,6 +657,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf
 github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg=
+github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
+github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
 github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
@@ -674,8 +676,8 @@ github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk
 github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
-github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A=
-github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
+github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4=
+github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI=
 github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
 github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
 github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
@@ -1404,6 +1406,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
 golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
@@ -1445,8 +1448,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
-golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
+golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1515,8 +1518,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
 golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
-golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
+golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
+golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
 golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1646,6 +1649,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
 golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
 golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
@@ -1737,8 +1741,8 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
-golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
-golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
+golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
+golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1772,8 +1776,8 @@ google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
 google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
 google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
 google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
-google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE=
-google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg=
+google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o=
+google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1826,8 +1830,12 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D
 google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
 google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
-google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
+google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 h1:Z0hjGZePRE0ZBWotvtrwxFNrNE9CUAGtplaDK5NNI/g=
+google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0=
+google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw=
+google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
 google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
@@ -1854,8 +1862,9 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ
 google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
 google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
 google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
-google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc=
-google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
+google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
+google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
+google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=

+ 8 - 8
vendor/cloud.google.com/go/.release-please-manifest-individual.json

@@ -1,13 +1,13 @@
 {
-  "bigquery": "1.46.0",
+  "bigquery": "1.52.0",
   "bigtable": "1.18.1",
-  "datastore": "1.10.0",
+  "datastore": "1.12.0",
   "errorreporting": "0.3.0",
-  "firestore": "1.9.0",
-  "logging": "1.6.1",
+  "firestore": "1.11.0",
+  "logging": "1.7.0",
   "profiler": "0.3.1",
-  "pubsub": "1.28.0",
-  "pubsublite": "1.6.0",
-  "spanner": "1.44.0",
-  "storage": "1.29.0"
+  "pubsub": "1.32.0",
+  "pubsublite": "1.8.1",
+  "spanner": "1.47.0",
+  "storage": "1.31.0"
 }

+ 123 - 114
vendor/cloud.google.com/go/.release-please-manifest-submodules.json

@@ -1,116 +1,125 @@
 {
-  "accessapproval": "1.6.0",
-  "accesscontextmanager": "1.6.0",
-  "aiplatform": "1.34.0",
-  "analytics": "0.17.0",
-  "apigateway": "1.5.0",
-  "apigeeconnect": "1.5.0",
-  "apigeeregistry": "0.3.0",
-  "apikeys": "0.3.0",
-  "appengine": "1.6.0",
-  "area120": "0.7.0",
-  "artifactregistry": "1.11.0",
-  "asset": "1.11.1",
-  "assuredworkloads": "1.10.0",
-  "automl": "1.12.0",
-  "baremetalsolution": "0.5.0",
-  "batch": "0.7.0",
-  "beyondcorp": "0.4.0",
-  "billing": "1.12.0",
-  "binaryauthorization": "1.5.0",
-  "certificatemanager": "1.6.0",
-  "channel": "1.11.0",
-  "cloudbuild": "1.6.0",
-  "clouddms": "1.5.0",
-  "cloudtasks": "1.9.0",
-  "compute": "1.18.0",
-  "compute/metadata": "0.2.3",
-  "contactcenterinsights": "1.6.0",
-  "container": "1.13.1",
-  "containeranalysis": "0.7.0",
-  "datacatalog": "1.12.0",
-  "dataflow": "0.8.0",
-  "dataform": "0.6.0",
-  "datafusion": "1.6.0",
-  "datalabeling": "0.7.0",
-  "dataplex": "1.5.2",
-  "dataproc": "1.12.0",
-  "dataqna": "0.7.0",
-  "datastream": "1.6.0",
-  "deploy": "1.6.0",
-  "dialogflow": "1.27.0",
-  "dlp": "1.9.0",
-  "documentai": "1.15.0",
-  "domains": "0.8.0",
-  "edgecontainer": "0.3.0",
-  "essentialcontacts": "1.5.0",
-  "eventarc": "1.10.0",
-  "filestore": "1.5.0",
-  "functions": "1.10.0",
-  "gaming": "1.9.0",
-  "gkebackup": "0.4.0",
-  "gkeconnect": "0.7.0",
-  "gkehub": "0.11.0",
-  "gkemulticloud": "0.5.0",
-  "grafeas": "0.2.0",
-  "gsuiteaddons": "1.5.0",
-  "iam": "0.10.0",
-  "iap": "1.6.0",
-  "ids": "1.3.0",
-  "iot": "1.5.0",
-  "kms": "1.8.0",
-  "language": "1.9.0",
-  "lifesciences": "0.8.0",
-  "longrunning": "0.4.1",
-  "managedidentities": "1.5.0",
-  "maps": "0.6.0",
-  "mediatranslation": "0.7.0",
-  "memcache": "1.9.0",
-  "metastore": "1.10.0",
-  "monitoring": "1.12.0",
-  "networkconnectivity": "1.10.0",
-  "networkmanagement": "1.6.0",
-  "networksecurity": "0.7.0",
-  "notebooks": "1.7.0",
-  "optimization": "1.3.1",
-  "orchestration": "1.6.0",
-  "orgpolicy": "1.10.0",
-  "osconfig": "1.11.0",
-  "oslogin": "1.9.0",
-  "phishingprotection": "0.7.0",
-  "policytroubleshooter": "1.5.0",
-  "privatecatalog": "0.7.0",
-  "recaptchaenterprise/v2": "2.6.0",
-  "recommendationengine": "0.7.0",
-  "recommender": "1.9.0",
-  "redis": "1.11.0",
-  "resourcemanager": "1.5.0",
-  "resourcesettings": "1.5.0",
-  "retail": "1.12.0",
-  "run": "0.8.0",
-  "scheduler": "1.8.0",
-  "secretmanager": "1.10.0",
-  "security": "1.12.0",
-  "securitycenter": "1.18.1",
-  "servicecontrol": "1.10.0",
-  "servicedirectory": "1.8.0",
-  "servicemanagement": "1.6.0",
-  "serviceusage": "1.5.0",
-  "shell": "1.6.0",
-  "speech": "1.14.1",
-  "storagetransfer": "1.7.0",
-  "talent": "1.5.0",
-  "texttospeech": "1.6.0",
-  "tpu": "1.5.0",
-  "trace": "1.8.0",
-  "translate": "1.5.0",
-  "video": "1.12.0",
-  "videointelligence": "1.10.0",
-  "vision/v2": "2.6.0",
-  "vmmigration": "1.5.0",
-  "vmwareengine": "0.2.2",
-  "vpcaccess": "1.6.0",
-  "webrisk": "1.8.0",
-  "websecurityscanner": "1.5.0",
-  "workflows": "1.10.0"
+    "accessapproval": "1.7.1",
+    "accesscontextmanager": "1.8.1",
+    "advisorynotifications": "0.3.1",
+    "aiplatform": "1.45.0",
+    "alloydb": "1.2.1",
+    "analytics": "0.21.2",
+    "apigateway": "1.6.1",
+    "apigeeconnect": "1.6.1",
+    "apigeeregistry": "0.7.1",
+    "apikeys": "1.1.1",
+    "appengine": "1.8.1",
+    "area120": "0.8.1",
+    "artifactregistry": "1.14.1",
+    "asset": "1.14.1",
+    "assuredworkloads": "1.11.1",
+    "automl": "1.13.1",
+    "baremetalsolution": "1.1.1",
+    "batch": "1.3.0",
+    "beyondcorp": "0.6.1",
+    "billing": "1.16.0",
+    "binaryauthorization": "1.6.1",
+    "certificatemanager": "1.7.1",
+    "channel": "1.16.0",
+    "cloudbuild": "1.10.1",
+    "clouddms": "1.6.1",
+    "cloudtasks": "1.11.1",
+    "compute": "1.20.1",
+    "compute/metadata": "0.2.3",
+    "confidentialcomputing": "0.3.1",
+    "contactcenterinsights": "1.9.1",
+    "container": "1.22.1",
+    "containeranalysis": "0.10.1",
+    "datacatalog": "1.14.1",
+    "dataflow": "0.9.1",
+    "dataform": "0.8.1",
+    "datafusion": "1.7.1",
+    "datalabeling": "0.8.1",
+    "dataplex": "1.8.1",
+    "dataproc": "2.0.1",
+    "dataqna": "0.8.1",
+    "datastream": "1.9.1",
+    "deploy": "1.11.0",
+    "dialogflow": "1.38.0",
+    "discoveryengine": "0.5.0",
+    "dlp": "1.10.1",
+    "documentai": "1.20.0",
+    "domains": "0.9.1",
+    "edgecontainer": "1.1.1",
+    "essentialcontacts": "1.6.2",
+    "eventarc": "1.12.1",
+    "filestore": "1.7.1",
+    "functions": "1.15.1",
+    "gaming": "1.10.1",
+    "gkebackup": "1.3.0",
+    "gkeconnect": "0.8.1",
+    "gkehub": "0.14.1",
+    "gkemulticloud": "0.6.1",
+    "grafeas": "0.3.1",
+    "gsuiteaddons": "1.6.1",
+    "iam": "1.1.1",
+    "iap": "1.8.1",
+    "ids": "1.4.1",
+    "iot": "1.7.1",
+    "kms": "1.12.1",
+    "language": "1.10.1",
+    "lifesciences": "0.9.1",
+    "longrunning": "0.5.1",
+    "managedidentities": "1.6.1",
+    "maps": "1.2.1",
+    "mediatranslation": "0.8.1",
+    "memcache": "1.10.1",
+    "metastore": "1.11.1",
+    "migrationcenter": "0.1.0",
+    "monitoring": "1.15.1",
+    "networkconnectivity": "1.12.1",
+    "networkmanagement": "1.8.0",
+    "networksecurity": "0.9.1",
+    "notebooks": "1.9.1",
+    "optimization": "1.4.1",
+    "orchestration": "1.8.1",
+    "orgpolicy": "1.11.1",
+    "osconfig": "1.12.1",
+    "oslogin": "1.10.1",
+    "phishingprotection": "0.8.1",
+    "policytroubleshooter": "1.7.1",
+    "privatecatalog": "0.9.1",
+    "rapidmigrationassessment": "0.1.2",
+    "recaptchaenterprise": "2.7.2",
+    "recommendationengine": "0.8.1",
+    "recommender": "1.10.1",
+    "redis": "1.13.1",
+    "resourcemanager": "1.9.1",
+    "resourcesettings": "1.6.1",
+    "retail": "1.14.1",
+    "run": "1.1.1",
+    "scheduler": "1.10.1",
+    "secretmanager": "1.11.1",
+    "security": "1.15.1",
+    "securitycenter": "1.23.0",
+    "servicecontrol": "1.12.1",
+    "servicedirectory": "1.10.1",
+    "servicemanagement": "1.9.2",
+    "serviceusage": "1.7.1",
+    "shell": "1.7.1",
+    "speech": "1.17.1",
+    "storageinsights": "0.2.2",
+    "storagetransfer": "1.10.0",
+    "support": "0.2.2",
+    "talent": "1.6.2",
+    "texttospeech": "1.7.1",
+    "tpu": "1.6.1",
+    "trace": "1.10.1",
+    "translate": "1.8.1",
+    "video": "1.17.1",
+    "videointelligence": "1.11.1",
+    "vision": "2.7.2",
+    "vmmigration": "1.7.1",
+    "vmwareengine": "0.4.1",
+    "vpcaccess": "1.7.1",
+    "webrisk": "1.9.1",
+    "websecurityscanner": "1.6.1",
+    "workflows": "1.11.1",
+    "workstations": "0.4.1"
 }

+ 1 - 1
vendor/cloud.google.com/go/.release-please-manifest.json

@@ -1,3 +1,3 @@
 {
-  ".": "0.110.0"
+  ".": "0.110.4"
 }

+ 33 - 0
vendor/cloud.google.com/go/CHANGES.md

@@ -1,5 +1,38 @@
 # Changes
 
+## [0.110.4](https://github.com/googleapis/google-cloud-go/compare/v0.110.3...v0.110.4) (2023-07-05)
+
+
+### Bug Fixes
+
+* **internal/retry:** Simplify gRPC status code mapping of retry error ([#8196](https://github.com/googleapis/google-cloud-go/issues/8196)) ([e8b224a](https://github.com/googleapis/google-cloud-go/commit/e8b224a3bcb0ca9430990ef6ae8ddb7b60f5225d))
+
+## [0.110.3](https://github.com/googleapis/google-cloud-go/compare/v0.110.2...v0.110.3) (2023-06-23)
+
+
+### Bug Fixes
+
+* **internal/retry:** Never return nil from GRPCStatus() ([#8128](https://github.com/googleapis/google-cloud-go/issues/8128)) ([005d2df](https://github.com/googleapis/google-cloud-go/commit/005d2dfb6b68bf5a35bfb8db449d3f0084b34d6e))
+
+
+### Documentation
+
+* **v1:** Minor clarifications for TaskGroup and min_cpu_platform ([3382ef8](https://github.com/googleapis/google-cloud-go/commit/3382ef81b6bcefe1c7bfc14aa5ff9bbf25850966))
+
+## [0.110.2](https://github.com/googleapis/google-cloud-go/compare/v0.110.1...v0.110.2) (2023-05-08)
+
+
+### Bug Fixes
+
+* **deps:** Update grpc to v1.55.0 ([#7885](https://github.com/googleapis/google-cloud-go/issues/7885)) ([9fc48a9](https://github.com/googleapis/google-cloud-go/commit/9fc48a921428c94c725ea90415d55ff0c177dd81))
+
+## [0.110.1](https://github.com/googleapis/google-cloud-go/compare/v0.110.0...v0.110.1) (2023-05-03)
+
+
+### Bug Fixes
+
+* **httpreplay:** Add ignore-header flag, fix tests ([#7865](https://github.com/googleapis/google-cloud-go/issues/7865)) ([1829706](https://github.com/googleapis/google-cloud-go/commit/1829706c5ade36cc786b2e6780fda5e7302f965b))
+
 ## [0.110.0](https://github.com/googleapis/google-cloud-go/compare/v0.109.0...v0.110.0) (2023-02-15)
 
 

+ 1 - 1
vendor/cloud.google.com/go/compute/internal/version.go

@@ -15,4 +15,4 @@
 package internal
 
 // Version is the current tagged release of the library.
-const Version = "1.19.1"
+const Version = "1.21.0"

+ 23 - 13
vendor/cloud.google.com/go/doc.go

@@ -94,13 +94,13 @@ cloud.google.com/go/secretmanager/apiv1 provides DefaultAuthScopes. Example:
 
 # Timeouts and Cancellation
 
-By default, non-streaming methods, like Create or Get, will have a default deadline applied to the
-context provided at call time, unless a context deadline is already set. Streaming
-methods have no default deadline and will run indefinitely. To set timeouts or
-arrange for cancellation, use contexts. Transient
-errors will be retried when correctness allows.
+By default, non-streaming methods, like Create or Get, will have a default
+deadline applied to the context provided at call time, unless a context deadline
+is already set. Streaming methods have no default deadline and will run
+indefinitely. To set timeouts or arrange for cancellation, use contexts.
+Transient errors will be retried when correctness allows.
 
-Here is an example of how to set a timeout for an RPC, use context.WithTimeout:
+Here is an example of setting a timeout for an RPC using context.WithTimeout:
 
 	ctx := context.Background()
 	// Do not set a timeout on the context passed to NewClient: dialing happens
@@ -119,6 +119,23 @@ Here is an example of how to set a timeout for an RPC, use context.WithTimeout:
 		// TODO: handle error.
 	}
 
+Here is an example of setting a timeout for an RPC using gax.WithTimeout:
+
+	ctx := context.Background()
+	// Do not set a timeout on the context passed to NewClient: dialing happens
+	// asynchronously, and the context is used to refresh credentials in the
+	// background.
+	client, err := secretmanager.NewClient(ctx)
+	if err != nil {
+		// TODO: handle error.
+	}
+
+	req := &secretmanagerpb.DeleteSecretRequest{Name: "projects/project-id/secrets/name"}
+	// Time out if it takes more than 10 seconds to create a dataset.
+	if err := client.DeleteSecret(tctx, req, gax.WithTimeout(10*time.Second)); err != nil {
+		// TODO: handle error.
+	}
+
 Here is an example of how to arrange for an RPC to be canceled, use context.WithCancel:
 
 	ctx := context.Background()
@@ -138,13 +155,6 @@ Here is an example of how to arrange for an RPC to be canceled, use context.With
 		// TODO: handle error.
 	}
 
-To opt out of default deadlines, set the temporary environment variable
-GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE to "true" prior to client
-creation. This affects all Google Cloud Go client libraries. This opt-out
-mechanism will be removed in a future release. File an issue at
-https://github.com/googleapis/google-cloud-go if the default deadlines
-cannot work for you.
-
 Do not attempt to control the initial connection (dialing) of a service by setting a
 timeout on the context passed to NewClient. Dialing is non-blocking, so timeouts
 would be ineffective and would only interfere with credential refreshing, which uses

+ 149 - 0
vendor/cloud.google.com/go/go.work

@@ -0,0 +1,149 @@
+go 1.18
+
+use (
+	.
+	./accessapproval
+	./accesscontextmanager
+	./advisorynotifications
+	./aiplatform
+	./alloydb
+	./analytics
+	./apigateway
+	./apigeeconnect
+	./apigeeregistry
+	./apikeys
+	./appengine
+	./area120
+	./artifactregistry
+	./asset
+	./assuredworkloads
+	./automl
+	./baremetalsolution
+	./batch
+	./beyondcorp
+	./bigquery
+	./bigtable
+	./billing
+	./binaryauthorization
+	./certificatemanager
+	./channel
+	./cloudbuild
+	./clouddms
+	./cloudtasks
+	./compute
+	./compute/metadata
+	./confidentialcomputing
+	./contactcenterinsights
+	./container
+	./containeranalysis
+	./datacatalog
+	./dataflow
+	./dataform
+	./datafusion
+	./datalabeling
+	./dataplex
+	./dataproc
+	./dataqna
+	./datastore
+	./datastream
+	./deploy
+	./dialogflow
+	./discoveryengine
+	./dlp
+	./documentai
+	./domains
+	./edgecontainer
+	./errorreporting
+	./essentialcontacts
+	./eventarc
+	./filestore
+	./firestore
+	./functions
+	./gaming
+	./gkebackup
+	./gkeconnect
+	./gkehub
+	./gkemulticloud
+	./grafeas
+	./gsuiteaddons
+	./iam
+	./iap
+	./ids
+	./internal/actions
+	./internal/aliasfix
+	./internal/aliasgen
+	./internal/carver
+	./internal/examples/fake
+	./internal/examples/mock
+	./internal/gapicgen
+	./internal/generated/snippets
+	./internal/godocfx
+	./internal/postprocessor
+	./iot
+	./kms
+	./language
+	./lifesciences
+	./logging
+	./longrunning
+	./managedidentities
+	./maps
+	./mediatranslation
+	./memcache
+	./metastore
+	./monitoring
+	./networkconnectivity
+	./networkmanagement
+	./networksecurity
+	./notebooks
+	./optimization
+	./orchestration
+	./orgpolicy
+	./osconfig
+	./oslogin
+	./phishingprotection
+	./policytroubleshooter
+	./privatecatalog
+	./profiler
+	./pubsub
+	./pubsublite
+	./rapidmigrationassessment
+	./recaptchaenterprise
+	./recommendationengine
+	./recommender
+	./redis
+	./resourcemanager
+	./resourcesettings
+	./retail
+	./run
+	./scheduler
+	./secretmanager
+	./security
+	./securitycenter
+	./servicecontrol
+	./servicedirectory
+	./servicemanagement
+	./serviceusage
+	./shell
+	./spanner
+	./speech
+	./storage
+	./storage/internal/benchmarks
+	./storageinsights
+	./storagetransfer
+	./support
+	./talent
+	./texttospeech
+	./tpu
+	./trace
+	./translate
+	./video
+	./videointelligence
+	./vision
+	./vmmigration
+	./vmwareengine
+	./vpcaccess
+	./webrisk
+	./websecurityscanner
+	./workflows
+	./workstations
+)

+ 21 - 0
vendor/cloud.google.com/go/go.work.sum

@@ -0,0 +1,21 @@
+github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
+github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
+github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
+github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
+github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
+github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
+github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
+github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
+github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
+github.com/googleapis/gax-go/v2 v2.9.1/go.mod h1:4FG3gMrVZlyMp5itSYKMU9z/lBE7+SbnUOvzH2HqbEY=
+github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
+github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
+github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM=
+github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
+golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
+golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
+golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
+golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
+golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
+google.golang.org/api v0.123.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms=

+ 21 - 0
vendor/cloud.google.com/go/longrunning/CHANGES.md

@@ -1,5 +1,26 @@
 # Changes
 
+## [0.5.1](https://github.com/googleapis/google-cloud-go/compare/longrunning/v0.5.0...longrunning/v0.5.1) (2023-06-20)
+
+
+### Bug Fixes
+
+* **longrunning:** REST query UpdateMask bug ([df52820](https://github.com/googleapis/google-cloud-go/commit/df52820b0e7721954809a8aa8700b93c5662dc9b))
+
+## [0.5.0](https://github.com/googleapis/google-cloud-go/compare/longrunning/v0.4.2...longrunning/v0.5.0) (2023-05-30)
+
+
+### Features
+
+* **longrunning:** Update all direct dependencies ([b340d03](https://github.com/googleapis/google-cloud-go/commit/b340d030f2b52a4ce48846ce63984b28583abde6))
+
+## [0.4.2](https://github.com/googleapis/google-cloud-go/compare/longrunning/v0.4.1...longrunning/v0.4.2) (2023-05-08)
+
+
+### Bug Fixes
+
+* **longrunning:** Update grpc to v1.55.0 ([1147ce0](https://github.com/googleapis/google-cloud-go/commit/1147ce02a990276ca4f8ab7a1ab65c14da4450ef))
+
 ## [0.4.1](https://github.com/googleapis/google-cloud-go/compare/longrunning/v0.4.0...longrunning/v0.4.1) (2023-02-14)
 
 

+ 5 - 64
vendor/cloud.google.com/go/longrunning/autogen/doc.go

@@ -17,8 +17,6 @@
 // Package longrunning is an auto-generated package for the
 // Long Running Operations API.
 //
-//	NOTE: This package is in alpha. It is not stable, and is likely to change.
-//
 // # General documentation
 //
 // For information about setting deadlines, reusing contexts, and more
@@ -77,6 +75,11 @@
 //		_ = resp
 //	}
 //
+// # Inspecting errors
+//
+// To see examples of how to inspect errors returned by this package please reference
+// [Inspecting errors](https://pkg.go.dev/cloud.google.com/go#hdr-Inspecting_errors).
+//
 // # Use of Context
 //
 // The ctx passed to NewOperationsClient is used for authentication requests and
@@ -88,13 +91,7 @@ package longrunning // import "cloud.google.com/go/longrunning/autogen"
 
 import (
 	"context"
-	"fmt"
 	"net/http"
-	"os"
-	"runtime"
-	"strconv"
-	"strings"
-	"unicode"
 
 	"google.golang.org/api/option"
 	"google.golang.org/grpc/metadata"
@@ -125,16 +122,6 @@ func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context {
 	return metadata.NewOutgoingContext(ctx, out)
 }
 
-func checkDisableDeadlines() (bool, error) {
-	raw, ok := os.LookupEnv("GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE")
-	if !ok {
-		return false, nil
-	}
-
-	b, err := strconv.ParseBool(raw)
-	return b, err
-}
-
 // DefaultAuthScopes reports the default set of authentication scopes to use with this package.
 func DefaultAuthScopes() []string {
 	return []string{
@@ -142,52 +129,6 @@ func DefaultAuthScopes() []string {
 	}
 }
 
-// versionGo returns the Go runtime version. The returned string
-// has no whitespace, suitable for reporting in header.
-func versionGo() string {
-	const develPrefix = "devel +"
-
-	s := runtime.Version()
-	if strings.HasPrefix(s, develPrefix) {
-		s = s[len(develPrefix):]
-		if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
-			s = s[:p]
-		}
-		return s
-	}
-
-	notSemverRune := func(r rune) bool {
-		return !strings.ContainsRune("0123456789.", r)
-	}
-
-	if strings.HasPrefix(s, "go1") {
-		s = s[2:]
-		var prerelease string
-		if p := strings.IndexFunc(s, notSemverRune); p >= 0 {
-			s, prerelease = s[:p], s[p:]
-		}
-		if strings.HasSuffix(s, ".") {
-			s += "0"
-		} else if strings.Count(s, ".") < 2 {
-			s += ".0"
-		}
-		if prerelease != "" {
-			s += "-" + prerelease
-		}
-		return s
-	}
-	return "UNKNOWN"
-}
-
-// maybeUnknownEnum wraps the given proto-JSON parsing error if it is the result
-// of receiving an unknown enum value.
-func maybeUnknownEnum(err error) error {
-	if strings.Contains(err.Error(), "invalid value for enum type") {
-		err = fmt.Errorf("received an unknown enum value; a later version of the library may support it: %w", err)
-	}
-	return err
-}
-
 // buildHeaders extracts metadata from the outgoing context, joins it with any other
 // given metadata, and converts them into a http.Header.
 func buildHeaders(ctx context.Context, mds ...metadata.MD) http.Header {

+ 26 - 27
vendor/cloud.google.com/go/longrunning/autogen/longrunningpb/operations.pb.go

@@ -14,8 +14,8 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.26.0
-// 	protoc        v3.21.12
+// 	protoc-gen-go v1.30.0
+// 	protoc        v4.23.2
 // source: google/longrunning/operations.proto
 
 package longrunningpb
@@ -70,7 +70,6 @@ type Operation struct {
 	// If `done` == `true`, exactly one of `error` or `response` is set.
 	//
 	// Types that are assignable to Result:
-	//
 	//	*Operation_Error
 	//	*Operation_Response
 	Result isOperation_Result `protobuf_oneof:"result"`
@@ -697,34 +696,34 @@ var file_google_longrunning_operations_proto_rawDesc = []byte{
 	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
 	0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73,
 	0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31,
-	0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x73, 0x7d, 0xda, 0x41, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,
+	0x6e, 0x73, 0x65, 0x22, 0x2b, 0xda, 0x41, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x66, 0x69, 0x6c,
+	0x74, 0x65, 0x72, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x7b,
+	0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x7d,
 	0x12, 0x7f, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
 	0x12, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75,
 	0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
 	0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
 	0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x4f,
-	0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a,
-	0x12, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x6f, 0x70, 0x65, 0x72,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d,
-	0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61,
+	0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x27, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61,
+	0x6d, 0x65, 0x3d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2a,
+	0x7d, 0x12, 0x7e, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61,
 	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6c, 0x6f,
 	0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
 	0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
 	0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
-	0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a,
-	0x2a, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x6f, 0x70, 0x65, 0x72,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d,
-	0x65, 0x12, 0x88, 0x01, 0x0a, 0x0f, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x4f, 0x70, 0x65, 0x72,
+	0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x27, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61,
+	0x6d, 0x65, 0x3d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2a,
+	0x7d, 0x12, 0x88, 0x01, 0x0a, 0x0f, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x4f, 0x70, 0x65, 0x72,
 	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6c,
 	0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65,
 	0x6c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
 	0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02,
-	0x24, 0x22, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x6f, 0x70, 0x65,
-	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2a, 0x7d, 0x3a, 0x63, 0x61, 0x6e, 0x63,
-	0x65, 0x6c, 0x3a, 0x01, 0x2a, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x5a, 0x0a, 0x0d,
+	0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x31, 0xda, 0x41, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x01, 0x2a, 0x22, 0x1f, 0x2f, 0x76, 0x31,
+	0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x73, 0x2f, 0x2a, 0x2a, 0x7d, 0x3a, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x12, 0x5a, 0x0a, 0x0d,
 	0x57, 0x61, 0x69, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x2e,
 	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69,
 	0x6e, 0x67, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
@@ -739,17 +738,17 @@ var file_google_longrunning_operations_proto_rawDesc = []byte{
 	0x32, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75,
 	0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49,
 	0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e,
-	0x66, 0x6f, 0x42, 0x97, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x66, 0x6f, 0x42, 0x9d, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
 	0x65, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x42, 0x0f, 0x4f,
 	0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
-	0x5a, 0x3d, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e,
-	0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f,
-	0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e,
-	0x69, 0x6e, 0x67, 0x3b, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0xf8,
-	0x01, 0x01, 0xaa, 0x02, 0x12, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x4c, 0x6f, 0x6e, 0x67,
-	0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0xca, 0x02, 0x12, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
-	0x5c, 0x4c, 0x6f, 0x6e, 0x67, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x33,
+	0x5a, 0x43, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63,
+	0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e,
+	0x67, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x67, 0x65, 0x6e, 0x2f, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75,
+	0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e,
+	0x69, 0x6e, 0x67, 0x70, 0x62, 0xf8, 0x01, 0x01, 0xaa, 0x02, 0x12, 0x47, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2e, 0x4c, 0x6f, 0x6e, 0x67, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0xca, 0x02, 0x12,
+	0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x4c, 0x6f, 0x6e, 0x67, 0x52, 0x75, 0x6e, 0x6e, 0x69,
+	0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (

+ 18 - 34
vendor/cloud.google.com/go/longrunning/autogen/operations_client.go

@@ -20,7 +20,7 @@ import (
 	"bytes"
 	"context"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"math"
 	"net/http"
 	"net/url"
@@ -67,6 +67,7 @@ func defaultOperationsGRPCClientOptions() []option.ClientOption {
 func defaultOperationsCallOptions() *OperationsCallOptions {
 	return &OperationsCallOptions{
 		ListOperations: []gax.CallOption{
+			gax.WithTimeout(10000 * time.Millisecond),
 			gax.WithRetry(func() gax.Retryer {
 				return gax.OnCodes([]codes.Code{
 					codes.Unavailable,
@@ -78,6 +79,7 @@ func defaultOperationsCallOptions() *OperationsCallOptions {
 			}),
 		},
 		GetOperation: []gax.CallOption{
+			gax.WithTimeout(10000 * time.Millisecond),
 			gax.WithRetry(func() gax.Retryer {
 				return gax.OnCodes([]codes.Code{
 					codes.Unavailable,
@@ -89,6 +91,7 @@ func defaultOperationsCallOptions() *OperationsCallOptions {
 			}),
 		},
 		DeleteOperation: []gax.CallOption{
+			gax.WithTimeout(10000 * time.Millisecond),
 			gax.WithRetry(func() gax.Retryer {
 				return gax.OnCodes([]codes.Code{
 					codes.Unavailable,
@@ -100,6 +103,7 @@ func defaultOperationsCallOptions() *OperationsCallOptions {
 			}),
 		},
 		CancelOperation: []gax.CallOption{
+			gax.WithTimeout(10000 * time.Millisecond),
 			gax.WithRetry(func() gax.Retryer {
 				return gax.OnCodes([]codes.Code{
 					codes.Unavailable,
@@ -117,6 +121,7 @@ func defaultOperationsCallOptions() *OperationsCallOptions {
 func defaultOperationsRESTCallOptions() *OperationsCallOptions {
 	return &OperationsCallOptions{
 		ListOperations: []gax.CallOption{
+			gax.WithTimeout(10000 * time.Millisecond),
 			gax.WithRetry(func() gax.Retryer {
 				return gax.OnHTTPCodes(gax.Backoff{
 					Initial:    500 * time.Millisecond,
@@ -127,6 +132,7 @@ func defaultOperationsRESTCallOptions() *OperationsCallOptions {
 			}),
 		},
 		GetOperation: []gax.CallOption{
+			gax.WithTimeout(10000 * time.Millisecond),
 			gax.WithRetry(func() gax.Retryer {
 				return gax.OnHTTPCodes(gax.Backoff{
 					Initial:    500 * time.Millisecond,
@@ -137,6 +143,7 @@ func defaultOperationsRESTCallOptions() *OperationsCallOptions {
 			}),
 		},
 		DeleteOperation: []gax.CallOption{
+			gax.WithTimeout(10000 * time.Millisecond),
 			gax.WithRetry(func() gax.Retryer {
 				return gax.OnHTTPCodes(gax.Backoff{
 					Initial:    500 * time.Millisecond,
@@ -147,6 +154,7 @@ func defaultOperationsRESTCallOptions() *OperationsCallOptions {
 			}),
 		},
 		CancelOperation: []gax.CallOption{
+			gax.WithTimeout(10000 * time.Millisecond),
 			gax.WithRetry(func() gax.Retryer {
 				return gax.OnHTTPCodes(gax.Backoff{
 					Initial:    500 * time.Millisecond,
@@ -278,9 +286,6 @@ type operationsGRPCClient struct {
 	// Connection pool of gRPC connections to the service.
 	connPool gtransport.ConnPool
 
-	// flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE
-	disableDeadlines bool
-
 	// Points back to the CallOptions field of the containing OperationsClient
 	CallOptions **OperationsCallOptions
 
@@ -313,11 +318,6 @@ func NewOperationsClient(ctx context.Context, opts ...option.ClientOption) (*Ope
 		clientOpts = append(clientOpts, hookOpts...)
 	}
 
-	disableDeadlines, err := checkDisableDeadlines()
-	if err != nil {
-		return nil, err
-	}
-
 	connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...)
 	if err != nil {
 		return nil, err
@@ -326,7 +326,6 @@ func NewOperationsClient(ctx context.Context, opts ...option.ClientOption) (*Ope
 
 	c := &operationsGRPCClient{
 		connPool:         connPool,
-		disableDeadlines: disableDeadlines,
 		operationsClient: longrunningpb.NewOperationsClient(connPool),
 		CallOptions:      &client.CallOptions,
 	}
@@ -349,7 +348,7 @@ func (c *operationsGRPCClient) Connection() *grpc.ClientConn {
 // the `x-goog-api-client` header passed on each request. Intended for
 // use by Google-written clients.
 func (c *operationsGRPCClient) setGoogleClientInfo(keyval ...string) {
-	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv := append([]string{"gl-go", gax.GoVersion}, keyval...)
 	kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "grpc", grpc.Version)
 	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
 }
@@ -417,7 +416,7 @@ func defaultOperationsRESTClientOptions() []option.ClientOption {
 // the `x-goog-api-client` header passed on each request. Intended for
 // use by Google-written clients.
 func (c *operationsRESTClient) setGoogleClientInfo(keyval ...string) {
-	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv := append([]string{"gl-go", gax.GoVersion}, keyval...)
 	kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "rest", "UNKNOWN")
 	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
 }
@@ -482,11 +481,6 @@ func (c *operationsGRPCClient) ListOperations(ctx context.Context, req *longrunn
 }
 
 func (c *operationsGRPCClient) GetOperation(ctx context.Context, req *longrunningpb.GetOperationRequest, opts ...gax.CallOption) (*longrunningpb.Operation, error) {
-	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
-		cctx, cancel := context.WithTimeout(ctx, 10000*time.Millisecond)
-		defer cancel()
-		ctx = cctx
-	}
 	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
 
 	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
@@ -504,11 +498,6 @@ func (c *operationsGRPCClient) GetOperation(ctx context.Context, req *longrunnin
 }
 
 func (c *operationsGRPCClient) DeleteOperation(ctx context.Context, req *longrunningpb.DeleteOperationRequest, opts ...gax.CallOption) error {
-	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
-		cctx, cancel := context.WithTimeout(ctx, 10000*time.Millisecond)
-		defer cancel()
-		ctx = cctx
-	}
 	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
 
 	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
@@ -522,11 +511,6 @@ func (c *operationsGRPCClient) DeleteOperation(ctx context.Context, req *longrun
 }
 
 func (c *operationsGRPCClient) CancelOperation(ctx context.Context, req *longrunningpb.CancelOperationRequest, opts ...gax.CallOption) error {
-	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
-		cctx, cancel := context.WithTimeout(ctx, 10000*time.Millisecond)
-		defer cancel()
-		ctx = cctx
-	}
 	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
 
 	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
@@ -619,13 +603,13 @@ func (c *operationsRESTClient) ListOperations(ctx context.Context, req *longrunn
 				return err
 			}
 
-			buf, err := ioutil.ReadAll(httpRsp.Body)
+			buf, err := io.ReadAll(httpRsp.Body)
 			if err != nil {
 				return err
 			}
 
 			if err := unm.Unmarshal(buf, resp); err != nil {
-				return maybeUnknownEnum(err)
+				return err
 			}
 
 			return nil
@@ -691,13 +675,13 @@ func (c *operationsRESTClient) GetOperation(ctx context.Context, req *longrunnin
 			return err
 		}
 
-		buf, err := ioutil.ReadAll(httpRsp.Body)
+		buf, err := io.ReadAll(httpRsp.Body)
 		if err != nil {
 			return err
 		}
 
 		if err := unm.Unmarshal(buf, resp); err != nil {
-			return maybeUnknownEnum(err)
+			return err
 		}
 
 		return nil
@@ -821,7 +805,7 @@ func (c *operationsRESTClient) WaitOperation(ctx context.Context, req *longrunni
 		if err != nil {
 			return nil, err
 		}
-		params.Add("timeout", string(timeout))
+		params.Add("timeout", string(timeout[1:len(timeout)-1]))
 	}
 
 	baseUrl.RawQuery = params.Encode()
@@ -852,13 +836,13 @@ func (c *operationsRESTClient) WaitOperation(ctx context.Context, req *longrunni
 			return err
 		}
 
-		buf, err := ioutil.ReadAll(httpRsp.Body)
+		buf, err := io.ReadAll(httpRsp.Body)
 		if err != nil {
 			return err
 		}
 
 		if err := unm.Unmarshal(buf, resp); err != nil {
-			return maybeUnknownEnum(err)
+			return err
 		}
 
 		return nil

+ 32 - 3
vendor/cloud.google.com/go/release-please-config-yoshi-submodules.json

@@ -9,9 +9,15 @@
         "accesscontextmanager": {
             "component": "accesscontextmanager"
         },
+        "advisorynotifications": {
+            "component": "advisorynotifications"
+        },
         "aiplatform": {
             "component": "aiplatform"
         },
+        "alloydb": {
+            "component": "alloydb"
+        },
         "analytics": {
             "component": "analytics"
         },
@@ -81,6 +87,9 @@
         "compute/metadata": {
             "component": "compute/metadata"
         },
+        "confidentialcomputing": {
+            "component": "confidentialcomputing"
+        },
         "contactcenterinsights": {
             "component": "contactcenterinsights"
         },
@@ -123,6 +132,9 @@
         "dialogflow": {
             "component": "dialogflow"
         },
+        "discoveryengine": {
+            "component": "discoveryengine"
+        },
         "dlp": {
             "component": "dlp"
         },
@@ -207,6 +219,9 @@
         "metastore": {
             "component": "metastore"
         },
+        "migrationcenter": {
+            "component": "migrationcenter"
+        },
         "monitoring": {
             "component": "monitoring"
         },
@@ -246,7 +261,10 @@
         "privatecatalog": {
             "component": "privatecatalog"
         },
-        "recaptchaenterprise/v2": {
+        "rapidmigrationassessment": {
+            "component": "rapidmigrationassessment"
+        },
+        "recaptchaenterprise": {
             "component": "recaptchaenterprise"
         },
         "recommendationengine": {
@@ -300,9 +318,15 @@
         "speech": {
             "component": "speech"
         },
+        "storageinsights": {
+            "component": "storageinsights"
+        },
         "storagetransfer": {
             "component": "storagetransfer"
         },
+        "support": {
+            "component": "support"
+        },
         "talent": {
             "component": "talent"
         },
@@ -324,7 +348,7 @@
         "videointelligence": {
             "component": "videointelligence"
         },
-        "vision/v2": {
+        "vision": {
             "component": "vision"
         },
         "vmmigration": {
@@ -344,7 +368,12 @@
         },
         "workflows": {
             "component": "workflows"
+        },
+        "workstations": {
+            "component": "workstations"
         }
     },
-    "plugins": ["sentence-case"]
+    "plugins": [
+        "sentence-case"
+    ]
 }

+ 5 - 0
vendor/github.com/containerd/containerd/Makefile

@@ -234,6 +234,11 @@ bin/cni-bridge-fp: integration/failpoint/cmd/cni-bridge-fp FORCE
 	@echo "$(WHALE) $@"
 	@$(GO) build ${GO_BUILD_FLAGS} -o $@ ./integration/failpoint/cmd/cni-bridge-fp
 
+# build runc-fp as runc wrapper to support failpoint, only used by integration test
+bin/runc-fp: integration/failpoint/cmd/runc-fp FORCE
+	@echo "$(WHALE) $@"
+	@$(GO) build ${GO_BUILD_FLAGS} -o $@ ./integration/failpoint/cmd/runc-fp
+
 benchmark: ## run benchmarks tests
 	@echo "$(WHALE) $@"
 	@$(GO) test ${TESTFLAGS} -bench . -run Benchmark -test.root

+ 1 - 1
vendor/github.com/containerd/containerd/Vagrantfile

@@ -102,7 +102,7 @@ EOF
   config.vm.provision "install-golang", type: "shell", run: "once" do |sh|
     sh.upload_path = "/tmp/vagrant-install-golang"
     sh.env = {
-        'GO_VERSION': ENV['GO_VERSION'] || "1.20.8",
+        'GO_VERSION': ENV['GO_VERSION'] || "1.20.10",
     }
     sh.inline = <<~SHELL
         #!/usr/bin/env bash

+ 18 - 0
vendor/github.com/containerd/containerd/oci/spec.go

@@ -18,6 +18,8 @@ package oci
 
 import (
 	"context"
+	"encoding/json"
+	"os"
 	"path/filepath"
 	"runtime"
 
@@ -43,6 +45,22 @@ var (
 // to be created without the "issues" with go vendoring and package imports
 type Spec = specs.Spec
 
+const ConfigFilename = "config.json"
+
+// ReadSpec deserializes JSON into an OCI runtime Spec from a given path.
+func ReadSpec(path string) (*Spec, error) {
+	f, err := os.Open(path)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	var s Spec
+	if err := json.NewDecoder(f).Decode(&s); err != nil {
+		return nil, err
+	}
+	return &s, nil
+}
+
 // GenerateSpec will generate a default spec from the provided image
 // for use as a containerd container
 func GenerateSpec(ctx context.Context, client Client, c *containers.Container, opts ...SpecOpts) (*Spec, error) {

+ 15 - 4
vendor/github.com/containerd/containerd/pull.go

@@ -34,7 +34,8 @@ import (
 )
 
 const (
-	pullSpanPrefix = "pull"
+	pullSpanPrefix                 = "pull"
+	convertedDockerSchema1LabelKey = "io.containerd.image/converted-docker-schema1"
 )
 
 // Pull downloads the provided content into containerd's content store
@@ -189,9 +190,10 @@ func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, lim
 	var (
 		handler images.Handler
 
-		isConvertible bool
-		converterFunc func(context.Context, ocispec.Descriptor) (ocispec.Descriptor, error)
-		limiter       *semaphore.Weighted
+		isConvertible         bool
+		originalSchema1Digest string
+		converterFunc         func(context.Context, ocispec.Descriptor) (ocispec.Descriptor, error)
+		limiter               *semaphore.Weighted
 	)
 
 	if desc.MediaType == images.MediaTypeDockerSchema1Manifest && rCtx.ConvertSchema1 {
@@ -204,6 +206,8 @@ func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, lim
 		converterFunc = func(ctx context.Context, _ ocispec.Descriptor) (ocispec.Descriptor, error) {
 			return schema1Converter.Convert(ctx)
 		}
+
+		originalSchema1Digest = desc.Digest.String()
 	} else {
 		// Get all the children for a descriptor
 		childrenHandler := images.ChildrenHandler(store)
@@ -270,6 +274,13 @@ func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, lim
 		}
 	}
 
+	if originalSchema1Digest != "" {
+		if rCtx.Labels == nil {
+			rCtx.Labels = make(map[string]string)
+		}
+		rCtx.Labels[convertedDockerSchema1LabelKey] = originalSchema1Digest
+	}
+
 	return images.Image{
 		Name:   name,
 		Target: desc,

+ 8 - 8
vendor/github.com/containerd/containerd/remotes/docker/authorizer.go

@@ -186,15 +186,15 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
 				return err
 			}
 
-			if username != "" && secret != "" {
-				common := auth.TokenOptions{
-					Username: username,
-					Secret:   secret,
-				}
-
-				a.handlers[host] = newAuthHandler(a.client, a.header, c.Scheme, common)
-				return nil
+			if username == "" || secret == "" {
+				return fmt.Errorf("%w: no basic auth credentials", ErrInvalidAuthorization)
 			}
+
+			a.handlers[host] = newAuthHandler(a.client, a.header, c.Scheme, auth.TokenOptions{
+				Username: username,
+				Secret:   secret,
+			})
+			return nil
 		}
 	}
 	return fmt.Errorf("failed to find supported auth scheme: %w", errdefs.ErrNotImplemented)

+ 7 - 4
vendor/github.com/containerd/containerd/remotes/docker/pusher.go

@@ -249,13 +249,16 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str
 			}
 
 			if lurl.Host != lhost.Host || lhost.Scheme != lurl.Scheme {
-
 				lhost.Scheme = lurl.Scheme
 				lhost.Host = lurl.Host
-				log.G(ctx).WithField("host", lhost.Host).WithField("scheme", lhost.Scheme).Debug("upload changed destination")
 
-				// Strip authorizer if change to host or scheme
-				lhost.Authorizer = nil
+				// Check if different than what was requested, accounting for fallback in the transport layer
+				requested := resp.Request.URL
+				if requested.Host != lhost.Host || requested.Scheme != lhost.Scheme {
+					// Strip authorizer if change to host or scheme
+					lhost.Authorizer = nil
+					log.G(ctx).WithField("host", lhost.Host).WithField("scheme", lhost.Scheme).Debug("upload changed destination, authorizer removed")
+				}
 			}
 		}
 		q := lurl.Query()

+ 1 - 1
vendor/github.com/containerd/containerd/version/version.go

@@ -23,7 +23,7 @@ var (
 	Package = "github.com/containerd/containerd"
 
 	// Version holds the complete version number. Filled in at linking time.
-	Version = "1.7.7+unknown"
+	Version = "1.7.8+unknown"
 
 	// Revision is filled with the VCS (e.g. git) revision being used to build
 	// the program at linking time.

+ 6 - 0
vendor/github.com/google/s2a-go/.gitignore

@@ -0,0 +1,6 @@
+# Ignore binaries without extension
+//example/client/client
+//example/server/server
+//internal/v2/fakes2av2_server/fakes2av2_server
+
+.idea/

+ 93 - 0
vendor/github.com/google/s2a-go/CODE_OF_CONDUCT.md

@@ -0,0 +1,93 @@
+# Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, gender identity and expression, level of
+experience, education, socio-economic status, nationality, personal appearance,
+race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+*   Using welcoming and inclusive language
+*   Being respectful of differing viewpoints and experiences
+*   Gracefully accepting constructive criticism
+*   Focusing on what is best for the community
+*   Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+*   The use of sexualized language or imagery and unwelcome sexual attention or
+    advances
+*   Trolling, insulting/derogatory comments, and personal or political attacks
+*   Public or private harassment
+*   Publishing others' private information, such as a physical or electronic
+    address, without explicit permission
+*   Other conduct which could reasonably be considered inappropriate in a
+    professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, or to ban temporarily or permanently any
+contributor for other behaviors that they deem inappropriate, threatening,
+offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+This Code of Conduct also applies outside the project spaces when the Project
+Steward has a reasonable belief that an individual's behavior may have a
+negative impact on the project or its community.
+
+## Conflict Resolution
+
+We do not believe that all conflict is bad; healthy debate and disagreement
+often yield positive results. However, it is never okay to be disrespectful or
+to engage in behavior that violates the project’s code of conduct.
+
+If you see someone violating the code of conduct, you are encouraged to address
+the behavior directly with those involved. Many issues can be resolved quickly
+and easily, and this gives people more control over the outcome of their
+dispute. If you are unable to resolve the matter for any reason, or if the
+behavior is threatening or harassing, report it. We are dedicated to providing
+an environment where participants feel welcome and safe.
+
+Reports should be directed to *[PROJECT STEWARD NAME(s) AND EMAIL(s)]*, the
+Project Steward(s) for *[PROJECT NAME]*. It is the Project Steward’s duty to
+receive and address reported violations of the code of conduct. They will then
+work with a committee consisting of representatives from the Open Source
+Programs Office and the Google Open Source Strategy team. If for any reason you
+are uncomfortable reaching out to the Project Steward, please email
+opensource@google.com.
+
+We will investigate every complaint, but you may not receive a direct response.
+We will use our discretion in determining when and how to follow up on reported
+incidents, which may range from not taking action to permanent expulsion from
+the project and project-sponsored spaces. We will notify the accused of the
+report and provide them an opportunity to discuss it before any action is taken.
+The identity of the reporter will be omitted from the details of the report
+supplied to the accused. In potentially harmful situations, such as ongoing
+harassment or threats to anyone's safety, we may take action without notice.
+
+## Attribution
+
+This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
+available at
+https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

+ 29 - 0
vendor/github.com/google/s2a-go/CONTRIBUTING.md

@@ -0,0 +1,29 @@
+# How to Contribute
+
+We'd love to accept your patches and contributions to this project. There are
+just a few small guidelines you need to follow.
+
+## Contributor License Agreement
+
+Contributions to this project must be accompanied by a Contributor License
+Agreement (CLA). You (or your employer) retain the copyright to your
+contribution; this simply gives us permission to use and redistribute your
+contributions as part of the project. Head over to
+<https://cla.developers.google.com/> to see your current agreements on file or
+to sign a new one.
+
+You generally only need to submit a CLA once, so if you've already submitted one
+(even if it was for a different project), you probably don't need to do it
+again.
+
+## Code reviews
+
+All submissions, including submissions by project members, require review. We
+use GitHub pull requests for this purpose. Consult
+[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
+information on using pull requests.
+
+## Community Guidelines
+
+This project follows
+[Google's Open Source Community Guidelines](https://opensource.google/conduct/).

+ 202 - 0
vendor/github.com/google/s2a-go/LICENSE.md

@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 17 - 0
vendor/github.com/google/s2a-go/README.md

@@ -0,0 +1,17 @@
+# Secure Session Agent Client Libraries
+
+The Secure Session Agent is a service that enables a workload to offload select
+operations from the mTLS handshake and protects a workload's private key
+material from exfiltration. Specifically, the workload asks the Secure Session
+Agent for the TLS configuration to use during the handshake, to perform private
+key operations, and to validate the peer certificate chain. The Secure Session
+Agent's client libraries enable applications to communicate with the Secure
+Session Agent during the TLS handshake, and to encrypt traffic to the peer
+after the TLS handshake is complete.
+
+This repository contains the source code for the Secure Session Agent's Go
+client libraries, which allow gRPC-Go applications to use the Secure Session
+Agent. This repository supports the Bazel and Golang build systems.
+
+All code in this repository is experimental and subject to change. We do not
+guarantee API stability at this time.

+ 167 - 0
vendor/github.com/google/s2a-go/fallback/s2a_fallback.go

@@ -0,0 +1,167 @@
+/*
+ *
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package fallback provides default implementations of fallback options when S2A fails.
+package fallback
+
+import (
+	"context"
+	"crypto/tls"
+	"fmt"
+	"net"
+
+	"google.golang.org/grpc/credentials"
+	"google.golang.org/grpc/grpclog"
+)
+
+const (
+	alpnProtoStrH2   = "h2"
+	alpnProtoStrHTTP = "http/1.1"
+	defaultHTTPSPort = "443"
+)
+
+// FallbackTLSConfigGRPC is a tls.Config used by the DefaultFallbackClientHandshakeFunc function.
+// It supports GRPC use case, thus the alpn is set to 'h2'.
+var FallbackTLSConfigGRPC = tls.Config{
+	MinVersion:         tls.VersionTLS13,
+	ClientSessionCache: nil,
+	NextProtos:         []string{alpnProtoStrH2},
+}
+
+// FallbackTLSConfigHTTP is a tls.Config used by the DefaultFallbackDialerAndAddress func.
+// It supports the HTTP use case and the alpn is set to both 'http/1.1' and 'h2'.
+var FallbackTLSConfigHTTP = tls.Config{
+	MinVersion:         tls.VersionTLS13,
+	ClientSessionCache: nil,
+	NextProtos:         []string{alpnProtoStrH2, alpnProtoStrHTTP},
+}
+
+// ClientHandshake establishes a TLS connection and returns it, plus its auth info.
+// Inputs:
+//
+//	targetServer: the server attempted with S2A.
+//	conn: the tcp connection to the server at address targetServer that was passed into S2A's ClientHandshake func.
+//	            If fallback is successful, the `conn` should be closed.
+//	err: the error encountered when performing the client-side TLS handshake with S2A.
+type ClientHandshake func(ctx context.Context, targetServer string, conn net.Conn, err error) (net.Conn, credentials.AuthInfo, error)
+
+// DefaultFallbackClientHandshakeFunc returns a ClientHandshake function,
+// which establishes a TLS connection to the provided fallbackAddr, returns the new connection and its auth info.
+// Example use:
+//
+//	transportCreds, _ = s2a.NewClientCreds(&s2a.ClientOptions{
+//		S2AAddress: s2aAddress,
+//		FallbackOpts: &s2a.FallbackOptions{ // optional
+//			FallbackClientHandshakeFunc: fallback.DefaultFallbackClientHandshakeFunc(fallbackAddr),
+//		},
+//	})
+//
+// The fallback server's certificate must be verifiable using OS root store.
+// The fallbackAddr is expected to be a network address, e.g. example.com:port. If port is not specified,
+// it uses default port 443.
+// In the returned function's TLS config, ClientSessionCache is explicitly set to nil to disable TLS resumption,
+// and min TLS version is set to 1.3.
+func DefaultFallbackClientHandshakeFunc(fallbackAddr string) (ClientHandshake, error) {
+	var fallbackDialer = tls.Dialer{Config: &FallbackTLSConfigGRPC}
+	return defaultFallbackClientHandshakeFuncInternal(fallbackAddr, fallbackDialer.DialContext)
+}
+
+func defaultFallbackClientHandshakeFuncInternal(fallbackAddr string, dialContextFunc func(context.Context, string, string) (net.Conn, error)) (ClientHandshake, error) {
+	fallbackServerAddr, err := processFallbackAddr(fallbackAddr)
+	if err != nil {
+		if grpclog.V(1) {
+			grpclog.Infof("error processing fallback address [%s]: %v", fallbackAddr, err)
+		}
+		return nil, err
+	}
+	return func(ctx context.Context, targetServer string, conn net.Conn, s2aErr error) (net.Conn, credentials.AuthInfo, error) {
+		fbConn, fbErr := dialContextFunc(ctx, "tcp", fallbackServerAddr)
+		if fbErr != nil {
+			grpclog.Infof("dialing to fallback server %s failed: %v", fallbackServerAddr, fbErr)
+			return nil, nil, fmt.Errorf("dialing to fallback server %s failed: %v; S2A client handshake with %s error: %w", fallbackServerAddr, fbErr, targetServer, s2aErr)
+		}
+
+		tc, success := fbConn.(*tls.Conn)
+		if !success {
+			grpclog.Infof("the connection with fallback server is expected to be tls but isn't")
+			return nil, nil, fmt.Errorf("the connection with fallback server is expected to be tls but isn't; S2A client handshake with %s error: %w", targetServer, s2aErr)
+		}
+
+		tlsInfo := credentials.TLSInfo{
+			State: tc.ConnectionState(),
+			CommonAuthInfo: credentials.CommonAuthInfo{
+				SecurityLevel: credentials.PrivacyAndIntegrity,
+			},
+		}
+		if grpclog.V(1) {
+			grpclog.Infof("ConnectionState.NegotiatedProtocol: %v", tc.ConnectionState().NegotiatedProtocol)
+			grpclog.Infof("ConnectionState.HandshakeComplete: %v", tc.ConnectionState().HandshakeComplete)
+			grpclog.Infof("ConnectionState.ServerName: %v", tc.ConnectionState().ServerName)
+		}
+		conn.Close()
+		return fbConn, tlsInfo, nil
+	}, nil
+}
+
+// DefaultFallbackDialerAndAddress returns a TLS dialer and the network address to dial.
+// Example use:
+//
+//	    fallbackDialer, fallbackServerAddr := fallback.DefaultFallbackDialerAndAddress(fallbackAddr)
+//		dialTLSContext := s2a.NewS2aDialTLSContextFunc(&s2a.ClientOptions{
+//			S2AAddress:         s2aAddress, // required
+//			FallbackOpts: &s2a.FallbackOptions{
+//				FallbackDialer: &s2a.FallbackDialer{
+//					Dialer:     fallbackDialer,
+//					ServerAddr: fallbackServerAddr,
+//				},
+//			},
+//	})
+//
+// The fallback server's certificate should be verifiable using OS root store.
+// The fallbackAddr is expected to be a network address, e.g. example.com:port. If port is not specified,
+// it uses default port 443.
+// In the returned function's TLS config, ClientSessionCache is explicitly set to nil to disable TLS resumption,
+// and min TLS version is set to 1.3.
+func DefaultFallbackDialerAndAddress(fallbackAddr string) (*tls.Dialer, string, error) {
+	fallbackServerAddr, err := processFallbackAddr(fallbackAddr)
+	if err != nil {
+		if grpclog.V(1) {
+			grpclog.Infof("error processing fallback address [%s]: %v", fallbackAddr, err)
+		}
+		return nil, "", err
+	}
+	return &tls.Dialer{Config: &FallbackTLSConfigHTTP}, fallbackServerAddr, nil
+}
+
+func processFallbackAddr(fallbackAddr string) (string, error) {
+	var fallbackServerAddr string
+	var err error
+
+	if fallbackAddr == "" {
+		return "", fmt.Errorf("empty fallback address")
+	}
+	_, _, err = net.SplitHostPort(fallbackAddr)
+	if err != nil {
+		// fallbackAddr does not have port suffix
+		fallbackServerAddr = net.JoinHostPort(fallbackAddr, defaultHTTPSPort)
+	} else {
+		// FallbackServerAddr already has port suffix
+		fallbackServerAddr = fallbackAddr
+	}
+	return fallbackServerAddr, nil
+}

+ 119 - 0
vendor/github.com/google/s2a-go/internal/authinfo/authinfo.go

@@ -0,0 +1,119 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package authinfo provides authentication and authorization information that
+// results from the TLS handshake.
+package authinfo
+
+import (
+	"errors"
+
+	commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
+	contextpb "github.com/google/s2a-go/internal/proto/s2a_context_go_proto"
+	grpcpb "github.com/google/s2a-go/internal/proto/s2a_go_proto"
+	"google.golang.org/grpc/credentials"
+)
+
+var _ credentials.AuthInfo = (*S2AAuthInfo)(nil)
+
+const s2aAuthType = "s2a"
+
+// S2AAuthInfo exposes authentication and authorization information from the
+// S2A session result to the gRPC stack.
+type S2AAuthInfo struct {
+	s2aContext     *contextpb.S2AContext
+	commonAuthInfo credentials.CommonAuthInfo
+}
+
+// NewS2AAuthInfo returns a new S2AAuthInfo object from the S2A session result.
+func NewS2AAuthInfo(result *grpcpb.SessionResult) (credentials.AuthInfo, error) {
+	return newS2AAuthInfo(result)
+}
+
+func newS2AAuthInfo(result *grpcpb.SessionResult) (*S2AAuthInfo, error) {
+	if result == nil {
+		return nil, errors.New("NewS2aAuthInfo given nil session result")
+	}
+	return &S2AAuthInfo{
+		s2aContext: &contextpb.S2AContext{
+			ApplicationProtocol:  result.GetApplicationProtocol(),
+			TlsVersion:           result.GetState().GetTlsVersion(),
+			Ciphersuite:          result.GetState().GetTlsCiphersuite(),
+			PeerIdentity:         result.GetPeerIdentity(),
+			LocalIdentity:        result.GetLocalIdentity(),
+			PeerCertFingerprint:  result.GetPeerCertFingerprint(),
+			LocalCertFingerprint: result.GetLocalCertFingerprint(),
+			IsHandshakeResumed:   result.GetState().GetIsHandshakeResumed(),
+		},
+		commonAuthInfo: credentials.CommonAuthInfo{SecurityLevel: credentials.PrivacyAndIntegrity},
+	}, nil
+}
+
+// AuthType returns the authentication type.
+func (s *S2AAuthInfo) AuthType() string {
+	return s2aAuthType
+}
+
+// ApplicationProtocol returns the application protocol, e.g. "grpc".
+func (s *S2AAuthInfo) ApplicationProtocol() string {
+	return s.s2aContext.GetApplicationProtocol()
+}
+
+// TLSVersion returns the TLS version negotiated during the handshake.
+func (s *S2AAuthInfo) TLSVersion() commonpb.TLSVersion {
+	return s.s2aContext.GetTlsVersion()
+}
+
+// Ciphersuite returns the ciphersuite negotiated during the handshake.
+func (s *S2AAuthInfo) Ciphersuite() commonpb.Ciphersuite {
+	return s.s2aContext.GetCiphersuite()
+}
+
+// PeerIdentity returns the authenticated identity of the peer.
+func (s *S2AAuthInfo) PeerIdentity() *commonpb.Identity {
+	return s.s2aContext.GetPeerIdentity()
+}
+
+// LocalIdentity returns the local identity of the application used during
+// session setup.
+func (s *S2AAuthInfo) LocalIdentity() *commonpb.Identity {
+	return s.s2aContext.GetLocalIdentity()
+}
+
+// PeerCertFingerprint returns the SHA256 hash of the peer certificate used in
+// the S2A handshake.
+func (s *S2AAuthInfo) PeerCertFingerprint() []byte {
+	return s.s2aContext.GetPeerCertFingerprint()
+}
+
+// LocalCertFingerprint returns the SHA256 hash of the local certificate used
+// in the S2A handshake.
+func (s *S2AAuthInfo) LocalCertFingerprint() []byte {
+	return s.s2aContext.GetLocalCertFingerprint()
+}
+
+// IsHandshakeResumed returns true if a cached session was used to resume
+// the handshake.
+func (s *S2AAuthInfo) IsHandshakeResumed() bool {
+	return s.s2aContext.GetIsHandshakeResumed()
+}
+
+// SecurityLevel returns the security level of the connection.
+func (s *S2AAuthInfo) SecurityLevel() credentials.SecurityLevel {
+	return s.commonAuthInfo.SecurityLevel
+}

+ 438 - 0
vendor/github.com/google/s2a-go/internal/handshaker/handshaker.go

@@ -0,0 +1,438 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package handshaker communicates with the S2A handshaker service.
+package handshaker
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"sync"
+
+	"github.com/google/s2a-go/internal/authinfo"
+	commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
+	s2apb "github.com/google/s2a-go/internal/proto/s2a_go_proto"
+	"github.com/google/s2a-go/internal/record"
+	"github.com/google/s2a-go/internal/tokenmanager"
+	grpc "google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/credentials"
+	"google.golang.org/grpc/grpclog"
+)
+
+var (
+	// appProtocol contains the application protocol accepted by the handshaker.
+	appProtocol = "grpc"
+	// frameLimit is the maximum size of a frame in bytes.
+	frameLimit = 1024 * 64
+	// peerNotRespondingError is the error thrown when the peer doesn't respond.
+	errPeerNotResponding = errors.New("peer is not responding and re-connection should be attempted")
+)
+
+// Handshaker defines a handshaker interface.
+type Handshaker interface {
+	// ClientHandshake starts and completes a TLS handshake from the client side,
+	// and returns a secure connection along with additional auth information.
+	ClientHandshake(ctx context.Context) (net.Conn, credentials.AuthInfo, error)
+	// ServerHandshake starts and completes a TLS handshake from the server side,
+	// and returns a secure connection along with additional auth information.
+	ServerHandshake(ctx context.Context) (net.Conn, credentials.AuthInfo, error)
+	// Close terminates the Handshaker. It should be called when the handshake
+	// is complete.
+	Close() error
+}
+
+// ClientHandshakerOptions contains the options needed to configure the S2A
+// handshaker service on the client-side.
+type ClientHandshakerOptions struct {
+	// MinTLSVersion specifies the min TLS version supported by the client.
+	MinTLSVersion commonpb.TLSVersion
+	// MaxTLSVersion specifies the max TLS version supported by the client.
+	MaxTLSVersion commonpb.TLSVersion
+	// TLSCiphersuites is the ordered list of ciphersuites supported by the
+	// client.
+	TLSCiphersuites []commonpb.Ciphersuite
+	// TargetIdentities contains a list of allowed server identities. One of the
+	// target identities should match the peer identity in the handshake
+	// result; otherwise, the handshake fails.
+	TargetIdentities []*commonpb.Identity
+	// LocalIdentity is the local identity of the client application. If none is
+	// provided, then the S2A will choose the default identity.
+	LocalIdentity *commonpb.Identity
+	// TargetName is the allowed server name, which may be used for server
+	// authorization check by the S2A if it is provided.
+	TargetName string
+	// EnsureProcessSessionTickets allows users to wait and ensure that all
+	// available session tickets are sent to S2A before a process completes.
+	EnsureProcessSessionTickets *sync.WaitGroup
+}
+
+// ServerHandshakerOptions contains the options needed to configure the S2A
+// handshaker service on the server-side.
+type ServerHandshakerOptions struct {
+	// MinTLSVersion specifies the min TLS version supported by the server.
+	MinTLSVersion commonpb.TLSVersion
+	// MaxTLSVersion specifies the max TLS version supported by the server.
+	MaxTLSVersion commonpb.TLSVersion
+	// TLSCiphersuites is the ordered list of ciphersuites supported by the
+	// server.
+	TLSCiphersuites []commonpb.Ciphersuite
+	// LocalIdentities is the list of local identities that may be assumed by
+	// the server. If no local identity is specified, then the S2A chooses a
+	// default local identity.
+	LocalIdentities []*commonpb.Identity
+}
+
+// s2aHandshaker performs a TLS handshake using the S2A handshaker service.
+type s2aHandshaker struct {
+	// stream is used to communicate with the S2A handshaker service.
+	stream s2apb.S2AService_SetUpSessionClient
+	// conn is the connection to the peer.
+	conn net.Conn
+	// clientOpts should be non-nil iff the handshaker is client-side.
+	clientOpts *ClientHandshakerOptions
+	// serverOpts should be non-nil iff the handshaker is server-side.
+	serverOpts *ServerHandshakerOptions
+	// isClient determines if the handshaker is client or server side.
+	isClient bool
+	// hsAddr stores the address of the S2A handshaker service.
+	hsAddr string
+	// tokenManager manages access tokens for authenticating to S2A.
+	tokenManager tokenmanager.AccessTokenManager
+	// localIdentities is the set of local identities for whom the
+	// tokenManager should fetch a token when preparing a request to be
+	// sent to S2A.
+	localIdentities []*commonpb.Identity
+}
+
+// NewClientHandshaker creates an s2aHandshaker instance that performs a
+// client-side TLS handshake using the S2A handshaker service.
+func NewClientHandshaker(ctx context.Context, conn *grpc.ClientConn, c net.Conn, hsAddr string, opts *ClientHandshakerOptions) (Handshaker, error) {
+	stream, err := s2apb.NewS2AServiceClient(conn).SetUpSession(ctx, grpc.WaitForReady(true))
+	if err != nil {
+		return nil, err
+	}
+	tokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager()
+	if err != nil {
+		grpclog.Infof("failed to create single token access token manager: %v", err)
+	}
+	return newClientHandshaker(stream, c, hsAddr, opts, tokenManager), nil
+}
+
+func newClientHandshaker(stream s2apb.S2AService_SetUpSessionClient, c net.Conn, hsAddr string, opts *ClientHandshakerOptions, tokenManager tokenmanager.AccessTokenManager) *s2aHandshaker {
+	var localIdentities []*commonpb.Identity
+	if opts != nil {
+		localIdentities = []*commonpb.Identity{opts.LocalIdentity}
+	}
+	return &s2aHandshaker{
+		stream:          stream,
+		conn:            c,
+		clientOpts:      opts,
+		isClient:        true,
+		hsAddr:          hsAddr,
+		tokenManager:    tokenManager,
+		localIdentities: localIdentities,
+	}
+}
+
+// NewServerHandshaker creates an s2aHandshaker instance that performs a
+// server-side TLS handshake using the S2A handshaker service.
+func NewServerHandshaker(ctx context.Context, conn *grpc.ClientConn, c net.Conn, hsAddr string, opts *ServerHandshakerOptions) (Handshaker, error) {
+	stream, err := s2apb.NewS2AServiceClient(conn).SetUpSession(ctx, grpc.WaitForReady(true))
+	if err != nil {
+		return nil, err
+	}
+	tokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager()
+	if err != nil {
+		grpclog.Infof("failed to create single token access token manager: %v", err)
+	}
+	return newServerHandshaker(stream, c, hsAddr, opts, tokenManager), nil
+}
+
+func newServerHandshaker(stream s2apb.S2AService_SetUpSessionClient, c net.Conn, hsAddr string, opts *ServerHandshakerOptions, tokenManager tokenmanager.AccessTokenManager) *s2aHandshaker {
+	var localIdentities []*commonpb.Identity
+	if opts != nil {
+		localIdentities = opts.LocalIdentities
+	}
+	return &s2aHandshaker{
+		stream:          stream,
+		conn:            c,
+		serverOpts:      opts,
+		isClient:        false,
+		hsAddr:          hsAddr,
+		tokenManager:    tokenManager,
+		localIdentities: localIdentities,
+	}
+}
+
+// ClientHandshake performs a client-side TLS handshake using the S2A handshaker
+// service. When complete, returns a TLS connection.
+func (h *s2aHandshaker) ClientHandshake(_ context.Context) (net.Conn, credentials.AuthInfo, error) {
+	if !h.isClient {
+		return nil, nil, errors.New("only handshakers created using NewClientHandshaker can perform a client-side handshake")
+	}
+	// Extract the hostname from the target name. The target name is assumed to be an authority.
+	hostname, _, err := net.SplitHostPort(h.clientOpts.TargetName)
+	if err != nil {
+		// If the target name had no host port or could not be parsed, use it as is.
+		hostname = h.clientOpts.TargetName
+	}
+
+	// Prepare a client start message to send to the S2A handshaker service.
+	req := &s2apb.SessionReq{
+		ReqOneof: &s2apb.SessionReq_ClientStart{
+			ClientStart: &s2apb.ClientSessionStartReq{
+				ApplicationProtocols: []string{appProtocol},
+				MinTlsVersion:        h.clientOpts.MinTLSVersion,
+				MaxTlsVersion:        h.clientOpts.MaxTLSVersion,
+				TlsCiphersuites:      h.clientOpts.TLSCiphersuites,
+				TargetIdentities:     h.clientOpts.TargetIdentities,
+				LocalIdentity:        h.clientOpts.LocalIdentity,
+				TargetName:           hostname,
+			},
+		},
+		AuthMechanisms: h.getAuthMechanisms(),
+	}
+	conn, result, err := h.setUpSession(req)
+	if err != nil {
+		return nil, nil, err
+	}
+	authInfo, err := authinfo.NewS2AAuthInfo(result)
+	if err != nil {
+		return nil, nil, err
+	}
+	return conn, authInfo, nil
+}
+
+// ServerHandshake performs a server-side TLS handshake using the S2A handshaker
+// service. When complete, returns a TLS connection.
+func (h *s2aHandshaker) ServerHandshake(_ context.Context) (net.Conn, credentials.AuthInfo, error) {
+	if h.isClient {
+		return nil, nil, errors.New("only handshakers created using NewServerHandshaker can perform a server-side handshake")
+	}
+	p := make([]byte, frameLimit)
+	n, err := h.conn.Read(p)
+	if err != nil {
+		return nil, nil, err
+	}
+	// Prepare a server start message to send to the S2A handshaker service.
+	req := &s2apb.SessionReq{
+		ReqOneof: &s2apb.SessionReq_ServerStart{
+			ServerStart: &s2apb.ServerSessionStartReq{
+				ApplicationProtocols: []string{appProtocol},
+				MinTlsVersion:        h.serverOpts.MinTLSVersion,
+				MaxTlsVersion:        h.serverOpts.MaxTLSVersion,
+				TlsCiphersuites:      h.serverOpts.TLSCiphersuites,
+				LocalIdentities:      h.serverOpts.LocalIdentities,
+				InBytes:              p[:n],
+			},
+		},
+		AuthMechanisms: h.getAuthMechanisms(),
+	}
+	conn, result, err := h.setUpSession(req)
+	if err != nil {
+		return nil, nil, err
+	}
+	authInfo, err := authinfo.NewS2AAuthInfo(result)
+	if err != nil {
+		return nil, nil, err
+	}
+	return conn, authInfo, nil
+}
+
+// setUpSession proxies messages between the peer and the S2A handshaker
+// service.
+func (h *s2aHandshaker) setUpSession(req *s2apb.SessionReq) (net.Conn, *s2apb.SessionResult, error) {
+	resp, err := h.accessHandshakerService(req)
+	if err != nil {
+		return nil, nil, err
+	}
+	// Check if the returned status is an error.
+	if resp.GetStatus() != nil {
+		if got, want := resp.GetStatus().Code, uint32(codes.OK); got != want {
+			return nil, nil, fmt.Errorf("%v", resp.GetStatus().Details)
+		}
+	}
+	// Calculate the extra unread bytes from the Session. Attempting to consume
+	// more than the bytes sent will throw an error.
+	var extra []byte
+	if req.GetServerStart() != nil {
+		if resp.GetBytesConsumed() > uint32(len(req.GetServerStart().GetInBytes())) {
+			return nil, nil, errors.New("handshaker service consumed bytes value is out-of-bounds")
+		}
+		extra = req.GetServerStart().GetInBytes()[resp.GetBytesConsumed():]
+	}
+	result, extra, err := h.processUntilDone(resp, extra)
+	if err != nil {
+		return nil, nil, err
+	}
+	if result.GetLocalIdentity() == nil {
+		return nil, nil, errors.New("local identity must be populated in session result")
+	}
+
+	// Create a new TLS record protocol using the Session Result.
+	newConn, err := record.NewConn(&record.ConnParameters{
+		NetConn:                     h.conn,
+		Ciphersuite:                 result.GetState().GetTlsCiphersuite(),
+		TLSVersion:                  result.GetState().GetTlsVersion(),
+		InTrafficSecret:             result.GetState().GetInKey(),
+		OutTrafficSecret:            result.GetState().GetOutKey(),
+		UnusedBuf:                   extra,
+		InSequence:                  result.GetState().GetInSequence(),
+		OutSequence:                 result.GetState().GetOutSequence(),
+		HSAddr:                      h.hsAddr,
+		ConnectionID:                result.GetState().GetConnectionId(),
+		LocalIdentity:               result.GetLocalIdentity(),
+		EnsureProcessSessionTickets: h.ensureProcessSessionTickets(),
+	})
+	if err != nil {
+		return nil, nil, err
+	}
+	return newConn, result, nil
+}
+
+func (h *s2aHandshaker) ensureProcessSessionTickets() *sync.WaitGroup {
+	if h.clientOpts == nil {
+		return nil
+	}
+	return h.clientOpts.EnsureProcessSessionTickets
+}
+
+// accessHandshakerService sends the session request to the S2A handshaker
+// service and returns the session response.
+func (h *s2aHandshaker) accessHandshakerService(req *s2apb.SessionReq) (*s2apb.SessionResp, error) {
+	if err := h.stream.Send(req); err != nil {
+		return nil, err
+	}
+	resp, err := h.stream.Recv()
+	if err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
+
+// processUntilDone continues proxying messages between the peer and the S2A
+// handshaker service until the handshaker service returns the SessionResult at
+// the end of the handshake or an error occurs.
+func (h *s2aHandshaker) processUntilDone(resp *s2apb.SessionResp, unusedBytes []byte) (*s2apb.SessionResult, []byte, error) {
+	for {
+		if len(resp.OutFrames) > 0 {
+			if _, err := h.conn.Write(resp.OutFrames); err != nil {
+				return nil, nil, err
+			}
+		}
+		if resp.Result != nil {
+			return resp.Result, unusedBytes, nil
+		}
+		buf := make([]byte, frameLimit)
+		n, err := h.conn.Read(buf)
+		if err != nil && err != io.EOF {
+			return nil, nil, err
+		}
+		// If there is nothing to send to the handshaker service and nothing is
+		// received from the peer, then we are stuck. This covers the case when
+		// the peer is not responding. Note that handshaker service connection
+		// issues are caught in accessHandshakerService before we even get
+		// here.
+		if len(resp.OutFrames) == 0 && n == 0 {
+			return nil, nil, errPeerNotResponding
+		}
+		// Append extra bytes from the previous interaction with the handshaker
+		// service with the current buffer read from conn.
+		p := append(unusedBytes, buf[:n]...)
+		// From here on, p and unusedBytes point to the same slice.
+		resp, err = h.accessHandshakerService(&s2apb.SessionReq{
+			ReqOneof: &s2apb.SessionReq_Next{
+				Next: &s2apb.SessionNextReq{
+					InBytes: p,
+				},
+			},
+			AuthMechanisms: h.getAuthMechanisms(),
+		})
+		if err != nil {
+			return nil, nil, err
+		}
+
+		// Cache the local identity returned by S2A, if it is populated. This
+		// overwrites any existing local identities. This is done because, once the
+		// S2A has selected a local identity, then only that local identity should
+		// be asserted in future requests until the end of the current handshake.
+		if resp.GetLocalIdentity() != nil {
+			h.localIdentities = []*commonpb.Identity{resp.GetLocalIdentity()}
+		}
+
+		// Set unusedBytes based on the handshaker service response.
+		if resp.GetBytesConsumed() > uint32(len(p)) {
+			return nil, nil, errors.New("handshaker service consumed bytes value is out-of-bounds")
+		}
+		unusedBytes = p[resp.GetBytesConsumed():]
+	}
+}
+
+// Close shuts down the handshaker and the stream to the S2A handshaker service
+// when the handshake is complete. It should be called when the caller obtains
+// the secure connection at the end of the handshake.
+func (h *s2aHandshaker) Close() error {
+	return h.stream.CloseSend()
+}
+
+func (h *s2aHandshaker) getAuthMechanisms() []*s2apb.AuthenticationMechanism {
+	if h.tokenManager == nil {
+		return nil
+	}
+	// First handle the special case when no local identities have been provided
+	// by the application. In this case, an AuthenticationMechanism with no local
+	// identity will be sent.
+	if len(h.localIdentities) == 0 {
+		token, err := h.tokenManager.DefaultToken()
+		if err != nil {
+			grpclog.Infof("unable to get token for empty local identity: %v", err)
+			return nil
+		}
+		return []*s2apb.AuthenticationMechanism{
+			{
+				MechanismOneof: &s2apb.AuthenticationMechanism_Token{
+					Token: token,
+				},
+			},
+		}
+	}
+
+	// Next, handle the case where the application (or the S2A) has provided
+	// one or more local identities.
+	var authMechanisms []*s2apb.AuthenticationMechanism
+	for _, localIdentity := range h.localIdentities {
+		token, err := h.tokenManager.Token(localIdentity)
+		if err != nil {
+			grpclog.Infof("unable to get token for local identity %v: %v", localIdentity, err)
+			continue
+		}
+
+		authMechanism := &s2apb.AuthenticationMechanism{
+			Identity: localIdentity,
+			MechanismOneof: &s2apb.AuthenticationMechanism_Token{
+				Token: token,
+			},
+		}
+		authMechanisms = append(authMechanisms, authMechanism)
+	}
+	return authMechanisms
+}

+ 99 - 0
vendor/github.com/google/s2a-go/internal/handshaker/service/service.go

@@ -0,0 +1,99 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package service is a utility for calling the S2A handshaker service.
+package service
+
+import (
+	"context"
+	"net"
+	"os"
+	"strings"
+	"sync"
+	"time"
+
+	"google.golang.org/appengine"
+	"google.golang.org/appengine/socket"
+	grpc "google.golang.org/grpc"
+	"google.golang.org/grpc/grpclog"
+)
+
+// An environment variable, if true, opportunistically use AppEngine-specific dialer to call S2A.
+const enableAppEngineDialerEnv = "S2A_ENABLE_APP_ENGINE_DIALER"
+
+var (
+	// appEngineDialerHook is an AppEngine-specific dial option that is set
+	// during init time. If nil, then the application is not running on Google
+	// AppEngine.
+	appEngineDialerHook func(context.Context) grpc.DialOption
+	// mu guards hsConnMap and hsDialer.
+	mu sync.Mutex
+	// hsConnMap represents a mapping from an S2A handshaker service address
+	// to a corresponding connection to an S2A handshaker service instance.
+	hsConnMap = make(map[string]*grpc.ClientConn)
+	// hsDialer will be reassigned in tests.
+	hsDialer = grpc.Dial
+)
+
+func init() {
+	if !appengine.IsAppEngine() && !appengine.IsDevAppServer() {
+		return
+	}
+	appEngineDialerHook = func(ctx context.Context) grpc.DialOption {
+		return grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
+			return socket.DialTimeout(ctx, "tcp", addr, timeout)
+		})
+	}
+}
+
+// Dial dials the S2A handshaker service. If a connection has already been
+// established, this function returns it. Otherwise, a new connection is
+// created.
+func Dial(handshakerServiceAddress string) (*grpc.ClientConn, error) {
+	mu.Lock()
+	defer mu.Unlock()
+
+	hsConn, ok := hsConnMap[handshakerServiceAddress]
+	if !ok {
+		// Create a new connection to the S2A handshaker service. Note that
+		// this connection stays open until the application is closed.
+		grpcOpts := []grpc.DialOption{
+			grpc.WithInsecure(),
+		}
+		if enableAppEngineDialer() && appEngineDialerHook != nil {
+			if grpclog.V(1) {
+				grpclog.Info("Using AppEngine-specific dialer to talk to S2A.")
+			}
+			grpcOpts = append(grpcOpts, appEngineDialerHook(context.Background()))
+		}
+		var err error
+		hsConn, err = hsDialer(handshakerServiceAddress, grpcOpts...)
+		if err != nil {
+			return nil, err
+		}
+		hsConnMap[handshakerServiceAddress] = hsConn
+	}
+	return hsConn, nil
+}
+
+func enableAppEngineDialer() bool {
+	if strings.ToLower(os.Getenv(enableAppEngineDialerEnv)) == "true" {
+		return true
+	}
+	return false
+}

+ 389 - 0
vendor/github.com/google/s2a-go/internal/proto/common_go_proto/common.pb.go

@@ -0,0 +1,389 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.30.0
+// 	protoc        v3.21.12
+// source: internal/proto/common/common.proto
+
+package common_go_proto
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// The ciphersuites supported by S2A. The name determines the confidentiality,
+// and authentication ciphers as well as the hash algorithm used for PRF in
+// TLS 1.2 or HKDF in TLS 1.3. Thus, the components of the name are:
+//   - AEAD -- for encryption and authentication, e.g., AES_128_GCM.
+//   - Hash algorithm -- used in PRF or HKDF, e.g., SHA256.
+type Ciphersuite int32
+
+const (
+	Ciphersuite_AES_128_GCM_SHA256       Ciphersuite = 0
+	Ciphersuite_AES_256_GCM_SHA384       Ciphersuite = 1
+	Ciphersuite_CHACHA20_POLY1305_SHA256 Ciphersuite = 2
+)
+
+// Enum value maps for Ciphersuite.
+var (
+	Ciphersuite_name = map[int32]string{
+		0: "AES_128_GCM_SHA256",
+		1: "AES_256_GCM_SHA384",
+		2: "CHACHA20_POLY1305_SHA256",
+	}
+	Ciphersuite_value = map[string]int32{
+		"AES_128_GCM_SHA256":       0,
+		"AES_256_GCM_SHA384":       1,
+		"CHACHA20_POLY1305_SHA256": 2,
+	}
+)
+
+func (x Ciphersuite) Enum() *Ciphersuite {
+	p := new(Ciphersuite)
+	*p = x
+	return p
+}
+
+func (x Ciphersuite) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Ciphersuite) Descriptor() protoreflect.EnumDescriptor {
+	return file_internal_proto_common_common_proto_enumTypes[0].Descriptor()
+}
+
+func (Ciphersuite) Type() protoreflect.EnumType {
+	return &file_internal_proto_common_common_proto_enumTypes[0]
+}
+
+func (x Ciphersuite) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Ciphersuite.Descriptor instead.
+func (Ciphersuite) EnumDescriptor() ([]byte, []int) {
+	return file_internal_proto_common_common_proto_rawDescGZIP(), []int{0}
+}
+
+// The TLS versions supported by S2A's handshaker module.
+type TLSVersion int32
+
+const (
+	TLSVersion_TLS1_2 TLSVersion = 0
+	TLSVersion_TLS1_3 TLSVersion = 1
+)
+
+// Enum value maps for TLSVersion.
+var (
+	TLSVersion_name = map[int32]string{
+		0: "TLS1_2",
+		1: "TLS1_3",
+	}
+	TLSVersion_value = map[string]int32{
+		"TLS1_2": 0,
+		"TLS1_3": 1,
+	}
+)
+
+func (x TLSVersion) Enum() *TLSVersion {
+	p := new(TLSVersion)
+	*p = x
+	return p
+}
+
+func (x TLSVersion) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (TLSVersion) Descriptor() protoreflect.EnumDescriptor {
+	return file_internal_proto_common_common_proto_enumTypes[1].Descriptor()
+}
+
+func (TLSVersion) Type() protoreflect.EnumType {
+	return &file_internal_proto_common_common_proto_enumTypes[1]
+}
+
+func (x TLSVersion) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use TLSVersion.Descriptor instead.
+func (TLSVersion) EnumDescriptor() ([]byte, []int) {
+	return file_internal_proto_common_common_proto_rawDescGZIP(), []int{1}
+}
+
+type Identity struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Types that are assignable to IdentityOneof:
+	//
+	//	*Identity_SpiffeId
+	//	*Identity_Hostname
+	//	*Identity_Uid
+	//	*Identity_MdbUsername
+	//	*Identity_GaiaId
+	IdentityOneof isIdentity_IdentityOneof `protobuf_oneof:"identity_oneof"`
+	// Additional identity-specific attributes.
+	Attributes map[string]string `protobuf:"bytes,3,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *Identity) Reset() {
+	*x = Identity{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_common_common_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Identity) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Identity) ProtoMessage() {}
+
+func (x *Identity) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_common_common_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Identity.ProtoReflect.Descriptor instead.
+func (*Identity) Descriptor() ([]byte, []int) {
+	return file_internal_proto_common_common_proto_rawDescGZIP(), []int{0}
+}
+
+func (m *Identity) GetIdentityOneof() isIdentity_IdentityOneof {
+	if m != nil {
+		return m.IdentityOneof
+	}
+	return nil
+}
+
+func (x *Identity) GetSpiffeId() string {
+	if x, ok := x.GetIdentityOneof().(*Identity_SpiffeId); ok {
+		return x.SpiffeId
+	}
+	return ""
+}
+
+func (x *Identity) GetHostname() string {
+	if x, ok := x.GetIdentityOneof().(*Identity_Hostname); ok {
+		return x.Hostname
+	}
+	return ""
+}
+
+func (x *Identity) GetUid() string {
+	if x, ok := x.GetIdentityOneof().(*Identity_Uid); ok {
+		return x.Uid
+	}
+	return ""
+}
+
+func (x *Identity) GetMdbUsername() string {
+	if x, ok := x.GetIdentityOneof().(*Identity_MdbUsername); ok {
+		return x.MdbUsername
+	}
+	return ""
+}
+
+func (x *Identity) GetGaiaId() string {
+	if x, ok := x.GetIdentityOneof().(*Identity_GaiaId); ok {
+		return x.GaiaId
+	}
+	return ""
+}
+
+func (x *Identity) GetAttributes() map[string]string {
+	if x != nil {
+		return x.Attributes
+	}
+	return nil
+}
+
+type isIdentity_IdentityOneof interface {
+	isIdentity_IdentityOneof()
+}
+
+type Identity_SpiffeId struct {
+	// The SPIFFE ID of a connection endpoint.
+	SpiffeId string `protobuf:"bytes,1,opt,name=spiffe_id,json=spiffeId,proto3,oneof"`
+}
+
+type Identity_Hostname struct {
+	// The hostname of a connection endpoint.
+	Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3,oneof"`
+}
+
+type Identity_Uid struct {
+	// The UID of a connection endpoint.
+	Uid string `protobuf:"bytes,4,opt,name=uid,proto3,oneof"`
+}
+
+type Identity_MdbUsername struct {
+	// The MDB username of a connection endpoint.
+	MdbUsername string `protobuf:"bytes,5,opt,name=mdb_username,json=mdbUsername,proto3,oneof"`
+}
+
+type Identity_GaiaId struct {
+	// The Gaia ID of a connection endpoint.
+	GaiaId string `protobuf:"bytes,6,opt,name=gaia_id,json=gaiaId,proto3,oneof"`
+}
+
+func (*Identity_SpiffeId) isIdentity_IdentityOneof() {}
+
+func (*Identity_Hostname) isIdentity_IdentityOneof() {}
+
+func (*Identity_Uid) isIdentity_IdentityOneof() {}
+
+func (*Identity_MdbUsername) isIdentity_IdentityOneof() {}
+
+func (*Identity_GaiaId) isIdentity_IdentityOneof() {}
+
+var File_internal_proto_common_common_proto protoreflect.FileDescriptor
+
+var file_internal_proto_common_common_proto_rawDesc = []byte{
+	0x0a, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
+	0xb1, 0x02, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x1d, 0x0a, 0x09,
+	0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48,
+	0x00, 0x52, 0x08, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x08, 0x68,
+	0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52,
+	0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x75, 0x69, 0x64,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x23, 0x0a,
+	0x0c, 0x6d, 0x64, 0x62, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x6d, 0x64, 0x62, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61,
+	0x6d, 0x65, 0x12, 0x19, 0x0a, 0x07, 0x67, 0x61, 0x69, 0x61, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20,
+	0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x67, 0x61, 0x69, 0x61, 0x49, 0x64, 0x12, 0x43, 0x0a,
+	0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x23, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64,
+	0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+	0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
+	0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73,
+	0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
+	0x01, 0x42, 0x10, 0x0a, 0x0e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x6f, 0x6e,
+	0x65, 0x6f, 0x66, 0x2a, 0x5b, 0x0a, 0x0b, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69,
+	0x74, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43,
+	0x4d, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x45,
+	0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x47, 0x43, 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34,
+	0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x48, 0x41, 0x43, 0x48, 0x41, 0x32, 0x30, 0x5f, 0x50,
+	0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, 0x35, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x02,
+	0x2a, 0x24, 0x0a, 0x0a, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0a,
+	0x0a, 0x06, 0x54, 0x4c, 0x53, 0x31, 0x5f, 0x32, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x4c,
+	0x53, 0x31, 0x5f, 0x33, 0x10, 0x01, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
+	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x73, 0x32, 0x61, 0x2f,
+	0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63,
+	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_internal_proto_common_common_proto_rawDescOnce sync.Once
+	file_internal_proto_common_common_proto_rawDescData = file_internal_proto_common_common_proto_rawDesc
+)
+
+func file_internal_proto_common_common_proto_rawDescGZIP() []byte {
+	file_internal_proto_common_common_proto_rawDescOnce.Do(func() {
+		file_internal_proto_common_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_common_common_proto_rawDescData)
+	})
+	return file_internal_proto_common_common_proto_rawDescData
+}
+
+var file_internal_proto_common_common_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
+var file_internal_proto_common_common_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_internal_proto_common_common_proto_goTypes = []interface{}{
+	(Ciphersuite)(0), // 0: s2a.proto.Ciphersuite
+	(TLSVersion)(0),  // 1: s2a.proto.TLSVersion
+	(*Identity)(nil), // 2: s2a.proto.Identity
+	nil,              // 3: s2a.proto.Identity.AttributesEntry
+}
+var file_internal_proto_common_common_proto_depIdxs = []int32{
+	3, // 0: s2a.proto.Identity.attributes:type_name -> s2a.proto.Identity.AttributesEntry
+	1, // [1:1] is the sub-list for method output_type
+	1, // [1:1] is the sub-list for method input_type
+	1, // [1:1] is the sub-list for extension type_name
+	1, // [1:1] is the sub-list for extension extendee
+	0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_internal_proto_common_common_proto_init() }
+func file_internal_proto_common_common_proto_init() {
+	if File_internal_proto_common_common_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_internal_proto_common_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Identity); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	file_internal_proto_common_common_proto_msgTypes[0].OneofWrappers = []interface{}{
+		(*Identity_SpiffeId)(nil),
+		(*Identity_Hostname)(nil),
+		(*Identity_Uid)(nil),
+		(*Identity_MdbUsername)(nil),
+		(*Identity_GaiaId)(nil),
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_internal_proto_common_common_proto_rawDesc,
+			NumEnums:      2,
+			NumMessages:   2,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_internal_proto_common_common_proto_goTypes,
+		DependencyIndexes: file_internal_proto_common_common_proto_depIdxs,
+		EnumInfos:         file_internal_proto_common_common_proto_enumTypes,
+		MessageInfos:      file_internal_proto_common_common_proto_msgTypes,
+	}.Build()
+	File_internal_proto_common_common_proto = out.File
+	file_internal_proto_common_common_proto_rawDesc = nil
+	file_internal_proto_common_common_proto_goTypes = nil
+	file_internal_proto_common_common_proto_depIdxs = nil
+}

+ 267 - 0
vendor/github.com/google/s2a-go/internal/proto/s2a_context_go_proto/s2a_context.pb.go

@@ -0,0 +1,267 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.30.0
+// 	protoc        v3.21.12
+// source: internal/proto/s2a_context/s2a_context.proto
+
+package s2a_context_go_proto
+
+import (
+	common_go_proto "github.com/google/s2a-go/internal/proto/common_go_proto"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type S2AContext struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The application protocol negotiated for this connection, e.g., 'grpc'.
+	ApplicationProtocol string `protobuf:"bytes,1,opt,name=application_protocol,json=applicationProtocol,proto3" json:"application_protocol,omitempty"`
+	// The TLS version number that the S2A's handshaker module used to set up the
+	// session.
+	TlsVersion common_go_proto.TLSVersion `protobuf:"varint,2,opt,name=tls_version,json=tlsVersion,proto3,enum=s2a.proto.TLSVersion" json:"tls_version,omitempty"`
+	// The TLS ciphersuite negotiated by the S2A's handshaker module.
+	Ciphersuite common_go_proto.Ciphersuite `protobuf:"varint,3,opt,name=ciphersuite,proto3,enum=s2a.proto.Ciphersuite" json:"ciphersuite,omitempty"`
+	// The authenticated identity of the peer.
+	PeerIdentity *common_go_proto.Identity `protobuf:"bytes,4,opt,name=peer_identity,json=peerIdentity,proto3" json:"peer_identity,omitempty"`
+	// The local identity used during session setup. This could be:
+	//   - The local identity that the client specifies in ClientSessionStartReq.
+	//   - One of the local identities that the server specifies in
+	//     ServerSessionStartReq.
+	//   - If neither client or server specifies local identities, the S2A picks the
+	//     default one. In this case, this field will contain that identity.
+	LocalIdentity *common_go_proto.Identity `protobuf:"bytes,5,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"`
+	// The SHA256 hash of the peer certificate used in the handshake.
+	PeerCertFingerprint []byte `protobuf:"bytes,6,opt,name=peer_cert_fingerprint,json=peerCertFingerprint,proto3" json:"peer_cert_fingerprint,omitempty"`
+	// The SHA256 hash of the local certificate used in the handshake.
+	LocalCertFingerprint []byte `protobuf:"bytes,7,opt,name=local_cert_fingerprint,json=localCertFingerprint,proto3" json:"local_cert_fingerprint,omitempty"`
+	// Set to true if a cached session was reused to resume the handshake.
+	IsHandshakeResumed bool `protobuf:"varint,8,opt,name=is_handshake_resumed,json=isHandshakeResumed,proto3" json:"is_handshake_resumed,omitempty"`
+}
+
+func (x *S2AContext) Reset() {
+	*x = S2AContext{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_s2a_context_s2a_context_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *S2AContext) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*S2AContext) ProtoMessage() {}
+
+func (x *S2AContext) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_s2a_context_s2a_context_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use S2AContext.ProtoReflect.Descriptor instead.
+func (*S2AContext) Descriptor() ([]byte, []int) {
+	return file_internal_proto_s2a_context_s2a_context_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *S2AContext) GetApplicationProtocol() string {
+	if x != nil {
+		return x.ApplicationProtocol
+	}
+	return ""
+}
+
+func (x *S2AContext) GetTlsVersion() common_go_proto.TLSVersion {
+	if x != nil {
+		return x.TlsVersion
+	}
+	return common_go_proto.TLSVersion(0)
+}
+
+func (x *S2AContext) GetCiphersuite() common_go_proto.Ciphersuite {
+	if x != nil {
+		return x.Ciphersuite
+	}
+	return common_go_proto.Ciphersuite(0)
+}
+
+func (x *S2AContext) GetPeerIdentity() *common_go_proto.Identity {
+	if x != nil {
+		return x.PeerIdentity
+	}
+	return nil
+}
+
+func (x *S2AContext) GetLocalIdentity() *common_go_proto.Identity {
+	if x != nil {
+		return x.LocalIdentity
+	}
+	return nil
+}
+
+func (x *S2AContext) GetPeerCertFingerprint() []byte {
+	if x != nil {
+		return x.PeerCertFingerprint
+	}
+	return nil
+}
+
+func (x *S2AContext) GetLocalCertFingerprint() []byte {
+	if x != nil {
+		return x.LocalCertFingerprint
+	}
+	return nil
+}
+
+func (x *S2AContext) GetIsHandshakeResumed() bool {
+	if x != nil {
+		return x.IsHandshakeResumed
+	}
+	return false
+}
+
+var File_internal_proto_s2a_context_s2a_context_proto protoreflect.FileDescriptor
+
+var file_internal_proto_s2a_context_s2a_context_proto_rawDesc = []byte{
+	0x0a, 0x2c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2f, 0x73, 0x32, 0x61, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x73, 0x32, 0x61,
+	0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09,
+	0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72,
+	0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
+	0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc3, 0x03,
+	0x0a, 0x0a, 0x53, 0x32, 0x41, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x31, 0x0a, 0x14,
+	0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x61, 0x70, 0x70, 0x6c,
+	0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12,
+	0x36, 0x0a, 0x0b, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x74, 0x6c, 0x73,
+	0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0b, 0x63, 0x69, 0x70, 0x68, 0x65,
+	0x72, 0x73, 0x75, 0x69, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x73,
+	0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73,
+	0x75, 0x69, 0x74, 0x65, 0x52, 0x0b, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, 0x74,
+	0x65, 0x12, 0x38, 0x0a, 0x0d, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69,
+	0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0c, 0x70,
+	0x65, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x3a, 0x0a, 0x0e, 0x6c,
+	0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+	0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49,
+	0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x65, 0x65, 0x72, 0x5f,
+	0x63, 0x65, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+	0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74,
+	0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x6c,
+	0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72,
+	0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x14, 0x6c, 0x6f, 0x63,
+	0x61, 0x6c, 0x43, 0x65, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+	0x74, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x73, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b,
+	0x65, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52,
+	0x12, 0x69, 0x73, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x75,
+	0x6d, 0x65, 0x64, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
+	0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x73, 0x32, 0x61, 0x2f, 0x69, 0x6e, 0x74,
+	0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x32, 0x61, 0x5f,
+	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_internal_proto_s2a_context_s2a_context_proto_rawDescOnce sync.Once
+	file_internal_proto_s2a_context_s2a_context_proto_rawDescData = file_internal_proto_s2a_context_s2a_context_proto_rawDesc
+)
+
+func file_internal_proto_s2a_context_s2a_context_proto_rawDescGZIP() []byte {
+	file_internal_proto_s2a_context_s2a_context_proto_rawDescOnce.Do(func() {
+		file_internal_proto_s2a_context_s2a_context_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_s2a_context_s2a_context_proto_rawDescData)
+	})
+	return file_internal_proto_s2a_context_s2a_context_proto_rawDescData
+}
+
+var file_internal_proto_s2a_context_s2a_context_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_internal_proto_s2a_context_s2a_context_proto_goTypes = []interface{}{
+	(*S2AContext)(nil),               // 0: s2a.proto.S2AContext
+	(common_go_proto.TLSVersion)(0),  // 1: s2a.proto.TLSVersion
+	(common_go_proto.Ciphersuite)(0), // 2: s2a.proto.Ciphersuite
+	(*common_go_proto.Identity)(nil), // 3: s2a.proto.Identity
+}
+var file_internal_proto_s2a_context_s2a_context_proto_depIdxs = []int32{
+	1, // 0: s2a.proto.S2AContext.tls_version:type_name -> s2a.proto.TLSVersion
+	2, // 1: s2a.proto.S2AContext.ciphersuite:type_name -> s2a.proto.Ciphersuite
+	3, // 2: s2a.proto.S2AContext.peer_identity:type_name -> s2a.proto.Identity
+	3, // 3: s2a.proto.S2AContext.local_identity:type_name -> s2a.proto.Identity
+	4, // [4:4] is the sub-list for method output_type
+	4, // [4:4] is the sub-list for method input_type
+	4, // [4:4] is the sub-list for extension type_name
+	4, // [4:4] is the sub-list for extension extendee
+	0, // [0:4] is the sub-list for field type_name
+}
+
+func init() { file_internal_proto_s2a_context_s2a_context_proto_init() }
+func file_internal_proto_s2a_context_s2a_context_proto_init() {
+	if File_internal_proto_s2a_context_s2a_context_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_internal_proto_s2a_context_s2a_context_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*S2AContext); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_internal_proto_s2a_context_s2a_context_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   1,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_internal_proto_s2a_context_s2a_context_proto_goTypes,
+		DependencyIndexes: file_internal_proto_s2a_context_s2a_context_proto_depIdxs,
+		MessageInfos:      file_internal_proto_s2a_context_s2a_context_proto_msgTypes,
+	}.Build()
+	File_internal_proto_s2a_context_s2a_context_proto = out.File
+	file_internal_proto_s2a_context_s2a_context_proto_rawDesc = nil
+	file_internal_proto_s2a_context_s2a_context_proto_goTypes = nil
+	file_internal_proto_s2a_context_s2a_context_proto_depIdxs = nil
+}

+ 1377 - 0
vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a.pb.go

@@ -0,0 +1,1377 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.30.0
+// 	protoc        v3.21.12
+// source: internal/proto/s2a/s2a.proto
+
+package s2a_go_proto
+
+import (
+	common_go_proto "github.com/google/s2a-go/internal/proto/common_go_proto"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type AuthenticationMechanism struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// (Optional) Application may specify an identity associated to an
+	// authentication mechanism. Otherwise, S2A assumes that the authentication
+	// mechanism is associated with the default identity. If the default identity
+	// cannot be determined, session setup fails.
+	Identity *common_go_proto.Identity `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
+	// Types that are assignable to MechanismOneof:
+	//
+	//	*AuthenticationMechanism_Token
+	MechanismOneof isAuthenticationMechanism_MechanismOneof `protobuf_oneof:"mechanism_oneof"`
+}
+
+func (x *AuthenticationMechanism) Reset() {
+	*x = AuthenticationMechanism{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_s2a_s2a_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AuthenticationMechanism) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AuthenticationMechanism) ProtoMessage() {}
+
+func (x *AuthenticationMechanism) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_s2a_s2a_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AuthenticationMechanism.ProtoReflect.Descriptor instead.
+func (*AuthenticationMechanism) Descriptor() ([]byte, []int) {
+	return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *AuthenticationMechanism) GetIdentity() *common_go_proto.Identity {
+	if x != nil {
+		return x.Identity
+	}
+	return nil
+}
+
+func (m *AuthenticationMechanism) GetMechanismOneof() isAuthenticationMechanism_MechanismOneof {
+	if m != nil {
+		return m.MechanismOneof
+	}
+	return nil
+}
+
+func (x *AuthenticationMechanism) GetToken() string {
+	if x, ok := x.GetMechanismOneof().(*AuthenticationMechanism_Token); ok {
+		return x.Token
+	}
+	return ""
+}
+
+type isAuthenticationMechanism_MechanismOneof interface {
+	isAuthenticationMechanism_MechanismOneof()
+}
+
+type AuthenticationMechanism_Token struct {
+	// A token that the application uses to authenticate itself to the S2A.
+	Token string `protobuf:"bytes,2,opt,name=token,proto3,oneof"`
+}
+
+func (*AuthenticationMechanism_Token) isAuthenticationMechanism_MechanismOneof() {}
+
+type ClientSessionStartReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The application protocols supported by the client, e.g., "grpc".
+	ApplicationProtocols []string `protobuf:"bytes,1,rep,name=application_protocols,json=applicationProtocols,proto3" json:"application_protocols,omitempty"`
+	// (Optional) The minimum TLS version number that the S2A's handshaker module
+	// will use to set up the session. If this field is not provided, S2A will use
+	// the minimum version it supports.
+	MinTlsVersion common_go_proto.TLSVersion `protobuf:"varint,2,opt,name=min_tls_version,json=minTlsVersion,proto3,enum=s2a.proto.TLSVersion" json:"min_tls_version,omitempty"`
+	// (Optional) The maximum TLS version number that the S2A's handshaker module
+	// will use to set up the session. If this field is not provided, S2A will use
+	// the maximum version it supports.
+	MaxTlsVersion common_go_proto.TLSVersion `protobuf:"varint,3,opt,name=max_tls_version,json=maxTlsVersion,proto3,enum=s2a.proto.TLSVersion" json:"max_tls_version,omitempty"`
+	// The TLS ciphersuites that the client is willing to support.
+	TlsCiphersuites []common_go_proto.Ciphersuite `protobuf:"varint,4,rep,packed,name=tls_ciphersuites,json=tlsCiphersuites,proto3,enum=s2a.proto.Ciphersuite" json:"tls_ciphersuites,omitempty"`
+	// (Optional) Describes which server identities are acceptable by the client.
+	// If target identities are provided and none of them matches the peer
+	// identity of the server, session setup fails.
+	TargetIdentities []*common_go_proto.Identity `protobuf:"bytes,5,rep,name=target_identities,json=targetIdentities,proto3" json:"target_identities,omitempty"`
+	// (Optional) Application may specify a local identity. Otherwise, S2A chooses
+	// the default local identity. If the default identity cannot be determined,
+	// session setup fails.
+	LocalIdentity *common_go_proto.Identity `protobuf:"bytes,6,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"`
+	// The target name that is used by S2A to configure SNI in the TLS handshake.
+	// It is also used to perform server authorization check if avaiable. This
+	// check is intended to verify that the peer authenticated identity is
+	// authorized to run a service with the target name.
+	// This field MUST only contain the host portion of the server address. It
+	// MUST not contain the scheme or the port number. For example, if the server
+	// address is dns://www.example.com:443, the value of this field should be
+	// set to www.example.com.
+	TargetName string `protobuf:"bytes,7,opt,name=target_name,json=targetName,proto3" json:"target_name,omitempty"`
+}
+
+func (x *ClientSessionStartReq) Reset() {
+	*x = ClientSessionStartReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_s2a_s2a_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ClientSessionStartReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ClientSessionStartReq) ProtoMessage() {}
+
+func (x *ClientSessionStartReq) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_s2a_s2a_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ClientSessionStartReq.ProtoReflect.Descriptor instead.
+func (*ClientSessionStartReq) Descriptor() ([]byte, []int) {
+	return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *ClientSessionStartReq) GetApplicationProtocols() []string {
+	if x != nil {
+		return x.ApplicationProtocols
+	}
+	return nil
+}
+
+func (x *ClientSessionStartReq) GetMinTlsVersion() common_go_proto.TLSVersion {
+	if x != nil {
+		return x.MinTlsVersion
+	}
+	return common_go_proto.TLSVersion(0)
+}
+
+func (x *ClientSessionStartReq) GetMaxTlsVersion() common_go_proto.TLSVersion {
+	if x != nil {
+		return x.MaxTlsVersion
+	}
+	return common_go_proto.TLSVersion(0)
+}
+
+func (x *ClientSessionStartReq) GetTlsCiphersuites() []common_go_proto.Ciphersuite {
+	if x != nil {
+		return x.TlsCiphersuites
+	}
+	return nil
+}
+
+func (x *ClientSessionStartReq) GetTargetIdentities() []*common_go_proto.Identity {
+	if x != nil {
+		return x.TargetIdentities
+	}
+	return nil
+}
+
+func (x *ClientSessionStartReq) GetLocalIdentity() *common_go_proto.Identity {
+	if x != nil {
+		return x.LocalIdentity
+	}
+	return nil
+}
+
+func (x *ClientSessionStartReq) GetTargetName() string {
+	if x != nil {
+		return x.TargetName
+	}
+	return ""
+}
+
+type ServerSessionStartReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The application protocols supported by the server, e.g., "grpc".
+	ApplicationProtocols []string `protobuf:"bytes,1,rep,name=application_protocols,json=applicationProtocols,proto3" json:"application_protocols,omitempty"`
+	// (Optional) The minimum TLS version number that the S2A's handshaker module
+	// will use to set up the session. If this field is not provided, S2A will use
+	// the minimum version it supports.
+	MinTlsVersion common_go_proto.TLSVersion `protobuf:"varint,2,opt,name=min_tls_version,json=minTlsVersion,proto3,enum=s2a.proto.TLSVersion" json:"min_tls_version,omitempty"`
+	// (Optional) The maximum TLS version number that the S2A's handshaker module
+	// will use to set up the session. If this field is not provided, S2A will use
+	// the maximum version it supports.
+	MaxTlsVersion common_go_proto.TLSVersion `protobuf:"varint,3,opt,name=max_tls_version,json=maxTlsVersion,proto3,enum=s2a.proto.TLSVersion" json:"max_tls_version,omitempty"`
+	// The TLS ciphersuites that the server is willing to support.
+	TlsCiphersuites []common_go_proto.Ciphersuite `protobuf:"varint,4,rep,packed,name=tls_ciphersuites,json=tlsCiphersuites,proto3,enum=s2a.proto.Ciphersuite" json:"tls_ciphersuites,omitempty"`
+	// (Optional) A list of local identities supported by the server, if
+	// specified. Otherwise, S2A chooses the default local identity. If the
+	// default identity cannot be determined, session setup fails.
+	LocalIdentities []*common_go_proto.Identity `protobuf:"bytes,5,rep,name=local_identities,json=localIdentities,proto3" json:"local_identities,omitempty"`
+	// The byte representation of the first handshake message received from the
+	// client peer. It is possible that this first message is split into multiple
+	// chunks. In this case, the first chunk is sent using this field and the
+	// following chunks are sent using the in_bytes field of SessionNextReq
+	// Specifically, if the client peer is using S2A, this field contains the
+	// bytes in the out_frames field of SessionResp message that the client peer
+	// received from its S2A after initiating the handshake.
+	InBytes []byte `protobuf:"bytes,6,opt,name=in_bytes,json=inBytes,proto3" json:"in_bytes,omitempty"`
+}
+
+func (x *ServerSessionStartReq) Reset() {
+	*x = ServerSessionStartReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_s2a_s2a_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ServerSessionStartReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ServerSessionStartReq) ProtoMessage() {}
+
+func (x *ServerSessionStartReq) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_s2a_s2a_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ServerSessionStartReq.ProtoReflect.Descriptor instead.
+func (*ServerSessionStartReq) Descriptor() ([]byte, []int) {
+	return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *ServerSessionStartReq) GetApplicationProtocols() []string {
+	if x != nil {
+		return x.ApplicationProtocols
+	}
+	return nil
+}
+
+func (x *ServerSessionStartReq) GetMinTlsVersion() common_go_proto.TLSVersion {
+	if x != nil {
+		return x.MinTlsVersion
+	}
+	return common_go_proto.TLSVersion(0)
+}
+
+func (x *ServerSessionStartReq) GetMaxTlsVersion() common_go_proto.TLSVersion {
+	if x != nil {
+		return x.MaxTlsVersion
+	}
+	return common_go_proto.TLSVersion(0)
+}
+
+func (x *ServerSessionStartReq) GetTlsCiphersuites() []common_go_proto.Ciphersuite {
+	if x != nil {
+		return x.TlsCiphersuites
+	}
+	return nil
+}
+
+func (x *ServerSessionStartReq) GetLocalIdentities() []*common_go_proto.Identity {
+	if x != nil {
+		return x.LocalIdentities
+	}
+	return nil
+}
+
+func (x *ServerSessionStartReq) GetInBytes() []byte {
+	if x != nil {
+		return x.InBytes
+	}
+	return nil
+}
+
+type SessionNextReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The byte representation of session setup, i.e., handshake messages.
+	// Specifically:
+	//   - All handshake messages sent from the server to the client.
+	//   - All, except for the first, handshake messages sent from the client to
+	//     the server. Note that the first message is communicated to S2A using the
+	//     in_bytes field of ServerSessionStartReq.
+	//
+	// If the peer is using S2A, this field contains the bytes in the out_frames
+	// field of SessionResp message that the peer received from its S2A.
+	InBytes []byte `protobuf:"bytes,1,opt,name=in_bytes,json=inBytes,proto3" json:"in_bytes,omitempty"`
+}
+
+func (x *SessionNextReq) Reset() {
+	*x = SessionNextReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_s2a_s2a_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SessionNextReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SessionNextReq) ProtoMessage() {}
+
+func (x *SessionNextReq) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_s2a_s2a_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SessionNextReq.ProtoReflect.Descriptor instead.
+func (*SessionNextReq) Descriptor() ([]byte, []int) {
+	return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *SessionNextReq) GetInBytes() []byte {
+	if x != nil {
+		return x.InBytes
+	}
+	return nil
+}
+
+type ResumptionTicketReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The byte representation of a NewSessionTicket message received from the
+	// server.
+	InBytes [][]byte `protobuf:"bytes,1,rep,name=in_bytes,json=inBytes,proto3" json:"in_bytes,omitempty"`
+	// A connection identifier that was created and sent by S2A at the end of a
+	// handshake.
+	ConnectionId uint64 `protobuf:"varint,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"`
+	// The local identity that was used by S2A during session setup and included
+	// in |SessionResult|.
+	LocalIdentity *common_go_proto.Identity `protobuf:"bytes,3,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"`
+}
+
+func (x *ResumptionTicketReq) Reset() {
+	*x = ResumptionTicketReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_s2a_s2a_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ResumptionTicketReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ResumptionTicketReq) ProtoMessage() {}
+
+func (x *ResumptionTicketReq) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_s2a_s2a_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ResumptionTicketReq.ProtoReflect.Descriptor instead.
+func (*ResumptionTicketReq) Descriptor() ([]byte, []int) {
+	return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *ResumptionTicketReq) GetInBytes() [][]byte {
+	if x != nil {
+		return x.InBytes
+	}
+	return nil
+}
+
+func (x *ResumptionTicketReq) GetConnectionId() uint64 {
+	if x != nil {
+		return x.ConnectionId
+	}
+	return 0
+}
+
+func (x *ResumptionTicketReq) GetLocalIdentity() *common_go_proto.Identity {
+	if x != nil {
+		return x.LocalIdentity
+	}
+	return nil
+}
+
+type SessionReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Types that are assignable to ReqOneof:
+	//
+	//	*SessionReq_ClientStart
+	//	*SessionReq_ServerStart
+	//	*SessionReq_Next
+	//	*SessionReq_ResumptionTicket
+	ReqOneof isSessionReq_ReqOneof `protobuf_oneof:"req_oneof"`
+	// (Optional) The authentication mechanisms that the client wishes to use to
+	// authenticate to the S2A, ordered by preference. The S2A will always use the
+	// first authentication mechanism that appears in the list and is supported by
+	// the S2A.
+	AuthMechanisms []*AuthenticationMechanism `protobuf:"bytes,5,rep,name=auth_mechanisms,json=authMechanisms,proto3" json:"auth_mechanisms,omitempty"`
+}
+
+func (x *SessionReq) Reset() {
+	*x = SessionReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_s2a_s2a_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SessionReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SessionReq) ProtoMessage() {}
+
+func (x *SessionReq) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_s2a_s2a_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SessionReq.ProtoReflect.Descriptor instead.
+func (*SessionReq) Descriptor() ([]byte, []int) {
+	return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{5}
+}
+
+func (m *SessionReq) GetReqOneof() isSessionReq_ReqOneof {
+	if m != nil {
+		return m.ReqOneof
+	}
+	return nil
+}
+
+func (x *SessionReq) GetClientStart() *ClientSessionStartReq {
+	if x, ok := x.GetReqOneof().(*SessionReq_ClientStart); ok {
+		return x.ClientStart
+	}
+	return nil
+}
+
+func (x *SessionReq) GetServerStart() *ServerSessionStartReq {
+	if x, ok := x.GetReqOneof().(*SessionReq_ServerStart); ok {
+		return x.ServerStart
+	}
+	return nil
+}
+
+func (x *SessionReq) GetNext() *SessionNextReq {
+	if x, ok := x.GetReqOneof().(*SessionReq_Next); ok {
+		return x.Next
+	}
+	return nil
+}
+
+func (x *SessionReq) GetResumptionTicket() *ResumptionTicketReq {
+	if x, ok := x.GetReqOneof().(*SessionReq_ResumptionTicket); ok {
+		return x.ResumptionTicket
+	}
+	return nil
+}
+
+func (x *SessionReq) GetAuthMechanisms() []*AuthenticationMechanism {
+	if x != nil {
+		return x.AuthMechanisms
+	}
+	return nil
+}
+
+type isSessionReq_ReqOneof interface {
+	isSessionReq_ReqOneof()
+}
+
+type SessionReq_ClientStart struct {
+	// The client session setup request message.
+	ClientStart *ClientSessionStartReq `protobuf:"bytes,1,opt,name=client_start,json=clientStart,proto3,oneof"`
+}
+
+type SessionReq_ServerStart struct {
+	// The server session setup request message.
+	ServerStart *ServerSessionStartReq `protobuf:"bytes,2,opt,name=server_start,json=serverStart,proto3,oneof"`
+}
+
+type SessionReq_Next struct {
+	// The next session setup message request message.
+	Next *SessionNextReq `protobuf:"bytes,3,opt,name=next,proto3,oneof"`
+}
+
+type SessionReq_ResumptionTicket struct {
+	// The resumption ticket that is received from the server. This message is
+	// only accepted by S2A if it is running as a client and if it is received
+	// after session setup is complete. If S2A is running as a server and it
+	// receives this message, the session is terminated.
+	ResumptionTicket *ResumptionTicketReq `protobuf:"bytes,4,opt,name=resumption_ticket,json=resumptionTicket,proto3,oneof"`
+}
+
+func (*SessionReq_ClientStart) isSessionReq_ReqOneof() {}
+
+func (*SessionReq_ServerStart) isSessionReq_ReqOneof() {}
+
+func (*SessionReq_Next) isSessionReq_ReqOneof() {}
+
+func (*SessionReq_ResumptionTicket) isSessionReq_ReqOneof() {}
+
+type SessionState struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The TLS version number that the S2A's handshaker module used to set up the
+	// session.
+	TlsVersion common_go_proto.TLSVersion `protobuf:"varint,1,opt,name=tls_version,json=tlsVersion,proto3,enum=s2a.proto.TLSVersion" json:"tls_version,omitempty"`
+	// The TLS ciphersuite negotiated by the S2A's handshaker module.
+	TlsCiphersuite common_go_proto.Ciphersuite `protobuf:"varint,2,opt,name=tls_ciphersuite,json=tlsCiphersuite,proto3,enum=s2a.proto.Ciphersuite" json:"tls_ciphersuite,omitempty"`
+	// The sequence number of the next, incoming, TLS record.
+	InSequence uint64 `protobuf:"varint,3,opt,name=in_sequence,json=inSequence,proto3" json:"in_sequence,omitempty"`
+	// The sequence number of the next, outgoing, TLS record.
+	OutSequence uint64 `protobuf:"varint,4,opt,name=out_sequence,json=outSequence,proto3" json:"out_sequence,omitempty"`
+	// The key for the inbound direction.
+	InKey []byte `protobuf:"bytes,5,opt,name=in_key,json=inKey,proto3" json:"in_key,omitempty"`
+	// The key for the outbound direction.
+	OutKey []byte `protobuf:"bytes,6,opt,name=out_key,json=outKey,proto3" json:"out_key,omitempty"`
+	// The constant part of the record nonce for the outbound direction.
+	InFixedNonce []byte `protobuf:"bytes,7,opt,name=in_fixed_nonce,json=inFixedNonce,proto3" json:"in_fixed_nonce,omitempty"`
+	// The constant part of the record nonce for the inbound direction.
+	OutFixedNonce []byte `protobuf:"bytes,8,opt,name=out_fixed_nonce,json=outFixedNonce,proto3" json:"out_fixed_nonce,omitempty"`
+	// A connection identifier that can be provided to S2A to perform operations
+	// related to this connection. This identifier will be stored by the record
+	// protocol, and included in the |ResumptionTicketReq| message that is later
+	// sent back to S2A. This field is set only for client-side connections.
+	ConnectionId uint64 `protobuf:"varint,9,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"`
+	// Set to true if a cached session was reused to do an abbreviated handshake.
+	IsHandshakeResumed bool `protobuf:"varint,10,opt,name=is_handshake_resumed,json=isHandshakeResumed,proto3" json:"is_handshake_resumed,omitempty"`
+}
+
+func (x *SessionState) Reset() {
+	*x = SessionState{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_s2a_s2a_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SessionState) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SessionState) ProtoMessage() {}
+
+func (x *SessionState) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_s2a_s2a_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SessionState.ProtoReflect.Descriptor instead.
+func (*SessionState) Descriptor() ([]byte, []int) {
+	return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *SessionState) GetTlsVersion() common_go_proto.TLSVersion {
+	if x != nil {
+		return x.TlsVersion
+	}
+	return common_go_proto.TLSVersion(0)
+}
+
+func (x *SessionState) GetTlsCiphersuite() common_go_proto.Ciphersuite {
+	if x != nil {
+		return x.TlsCiphersuite
+	}
+	return common_go_proto.Ciphersuite(0)
+}
+
+func (x *SessionState) GetInSequence() uint64 {
+	if x != nil {
+		return x.InSequence
+	}
+	return 0
+}
+
+func (x *SessionState) GetOutSequence() uint64 {
+	if x != nil {
+		return x.OutSequence
+	}
+	return 0
+}
+
+func (x *SessionState) GetInKey() []byte {
+	if x != nil {
+		return x.InKey
+	}
+	return nil
+}
+
+func (x *SessionState) GetOutKey() []byte {
+	if x != nil {
+		return x.OutKey
+	}
+	return nil
+}
+
+func (x *SessionState) GetInFixedNonce() []byte {
+	if x != nil {
+		return x.InFixedNonce
+	}
+	return nil
+}
+
+func (x *SessionState) GetOutFixedNonce() []byte {
+	if x != nil {
+		return x.OutFixedNonce
+	}
+	return nil
+}
+
+func (x *SessionState) GetConnectionId() uint64 {
+	if x != nil {
+		return x.ConnectionId
+	}
+	return 0
+}
+
+func (x *SessionState) GetIsHandshakeResumed() bool {
+	if x != nil {
+		return x.IsHandshakeResumed
+	}
+	return false
+}
+
+type SessionResult struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The application protocol negotiated for this session.
+	ApplicationProtocol string `protobuf:"bytes,1,opt,name=application_protocol,json=applicationProtocol,proto3" json:"application_protocol,omitempty"`
+	// The session state at the end. This state contains all cryptographic
+	// material required to initialize the record protocol object.
+	State *SessionState `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"`
+	// The authenticated identity of the peer.
+	PeerIdentity *common_go_proto.Identity `protobuf:"bytes,4,opt,name=peer_identity,json=peerIdentity,proto3" json:"peer_identity,omitempty"`
+	// The local identity used during session setup. This could be:
+	//   - The local identity that the client specifies in ClientSessionStartReq.
+	//   - One of the local identities that the server specifies in
+	//     ServerSessionStartReq.
+	//   - If neither client or server specifies local identities, the S2A picks the
+	//     default one. In this case, this field will contain that identity.
+	LocalIdentity *common_go_proto.Identity `protobuf:"bytes,5,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"`
+	// The SHA256 hash of the local certificate used in the handshake.
+	LocalCertFingerprint []byte `protobuf:"bytes,6,opt,name=local_cert_fingerprint,json=localCertFingerprint,proto3" json:"local_cert_fingerprint,omitempty"`
+	// The SHA256 hash of the peer certificate used in the handshake.
+	PeerCertFingerprint []byte `protobuf:"bytes,7,opt,name=peer_cert_fingerprint,json=peerCertFingerprint,proto3" json:"peer_cert_fingerprint,omitempty"`
+}
+
+func (x *SessionResult) Reset() {
+	*x = SessionResult{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_s2a_s2a_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SessionResult) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SessionResult) ProtoMessage() {}
+
+func (x *SessionResult) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_s2a_s2a_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SessionResult.ProtoReflect.Descriptor instead.
+func (*SessionResult) Descriptor() ([]byte, []int) {
+	return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *SessionResult) GetApplicationProtocol() string {
+	if x != nil {
+		return x.ApplicationProtocol
+	}
+	return ""
+}
+
+func (x *SessionResult) GetState() *SessionState {
+	if x != nil {
+		return x.State
+	}
+	return nil
+}
+
+func (x *SessionResult) GetPeerIdentity() *common_go_proto.Identity {
+	if x != nil {
+		return x.PeerIdentity
+	}
+	return nil
+}
+
+func (x *SessionResult) GetLocalIdentity() *common_go_proto.Identity {
+	if x != nil {
+		return x.LocalIdentity
+	}
+	return nil
+}
+
+func (x *SessionResult) GetLocalCertFingerprint() []byte {
+	if x != nil {
+		return x.LocalCertFingerprint
+	}
+	return nil
+}
+
+func (x *SessionResult) GetPeerCertFingerprint() []byte {
+	if x != nil {
+		return x.PeerCertFingerprint
+	}
+	return nil
+}
+
+type SessionStatus struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The status code that is specific to the application and the implementation
+	// of S2A, e.g., gRPC status code.
+	Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
+	// The status details.
+	Details string `protobuf:"bytes,2,opt,name=details,proto3" json:"details,omitempty"`
+}
+
+func (x *SessionStatus) Reset() {
+	*x = SessionStatus{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_s2a_s2a_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SessionStatus) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SessionStatus) ProtoMessage() {}
+
+func (x *SessionStatus) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_s2a_s2a_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SessionStatus.ProtoReflect.Descriptor instead.
+func (*SessionStatus) Descriptor() ([]byte, []int) {
+	return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *SessionStatus) GetCode() uint32 {
+	if x != nil {
+		return x.Code
+	}
+	return 0
+}
+
+func (x *SessionStatus) GetDetails() string {
+	if x != nil {
+		return x.Details
+	}
+	return ""
+}
+
+type SessionResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The local identity used during session setup. This could be:
+	//   - The local identity that the client specifies in ClientSessionStartReq.
+	//   - One of the local identities that the server specifies in
+	//     ServerSessionStartReq.
+	//   - If neither client or server specifies local identities, the S2A picks the
+	//     default one. In this case, this field will contain that identity.
+	//
+	// If the SessionResult is populated, then this must coincide with the local
+	// identity specified in the SessionResult; otherwise, the handshake must
+	// fail.
+	LocalIdentity *common_go_proto.Identity `protobuf:"bytes,1,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"`
+	// The byte representation of the frames that should be sent to the peer. May
+	// be empty if nothing needs to be sent to the peer or if in_bytes in the
+	// SessionReq is incomplete. All bytes in a non-empty out_frames must be sent
+	// to the peer even if the session setup status is not OK as these frames may
+	// contain appropriate alerts.
+	OutFrames []byte `protobuf:"bytes,2,opt,name=out_frames,json=outFrames,proto3" json:"out_frames,omitempty"`
+	// Number of bytes in the in_bytes field that are consumed by S2A. It is
+	// possible that part of in_bytes is unrelated to the session setup process.
+	BytesConsumed uint32 `protobuf:"varint,3,opt,name=bytes_consumed,json=bytesConsumed,proto3" json:"bytes_consumed,omitempty"`
+	// This is set if the session is successfully set up. out_frames may
+	// still be set to frames that needs to be forwarded to the peer.
+	Result *SessionResult `protobuf:"bytes,4,opt,name=result,proto3" json:"result,omitempty"`
+	// Status of session setup at the current stage.
+	Status *SessionStatus `protobuf:"bytes,5,opt,name=status,proto3" json:"status,omitempty"`
+}
+
+func (x *SessionResp) Reset() {
+	*x = SessionResp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_s2a_s2a_proto_msgTypes[9]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SessionResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SessionResp) ProtoMessage() {}
+
+func (x *SessionResp) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_s2a_s2a_proto_msgTypes[9]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SessionResp.ProtoReflect.Descriptor instead.
+func (*SessionResp) Descriptor() ([]byte, []int) {
+	return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *SessionResp) GetLocalIdentity() *common_go_proto.Identity {
+	if x != nil {
+		return x.LocalIdentity
+	}
+	return nil
+}
+
+func (x *SessionResp) GetOutFrames() []byte {
+	if x != nil {
+		return x.OutFrames
+	}
+	return nil
+}
+
+func (x *SessionResp) GetBytesConsumed() uint32 {
+	if x != nil {
+		return x.BytesConsumed
+	}
+	return 0
+}
+
+func (x *SessionResp) GetResult() *SessionResult {
+	if x != nil {
+		return x.Result
+	}
+	return nil
+}
+
+func (x *SessionResp) GetStatus() *SessionStatus {
+	if x != nil {
+		return x.Status
+	}
+	return nil
+}
+
+var File_internal_proto_s2a_s2a_proto protoreflect.FileDescriptor
+
+var file_internal_proto_s2a_s2a_proto_rawDesc = []byte{
+	0x0a, 0x1c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2f, 0x73, 0x32, 0x61, 0x2f, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09,
+	0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72,
+	0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
+	0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x75, 0x0a,
+	0x17, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d,
+	0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x12, 0x2f, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e,
+	0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52,
+	0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x6f, 0x6b,
+	0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65,
+	0x6e, 0x42, 0x11, 0x0a, 0x0f, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x5f, 0x6f,
+	0x6e, 0x65, 0x6f, 0x66, 0x22, 0xac, 0x03, 0x0a, 0x15, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53,
+	0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x12, 0x33,
+	0x0a, 0x15, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x61,
+	0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63,
+	0x6f, 0x6c, 0x73, 0x12, 0x3d, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76,
+	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73,
+	0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73,
+	0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x54, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69,
+	0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65,
+	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73, 0x32,
+	0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69,
+	0x6f, 0x6e, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x54, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+	0x6e, 0x12, 0x41, 0x0a, 0x10, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73,
+	0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x73, 0x32,
+	0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75,
+	0x69, 0x74, 0x65, 0x52, 0x0f, 0x74, 0x6c, 0x73, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75,
+	0x69, 0x74, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x11, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x69,
+	0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e,
+	0x74, 0x69, 0x74, 0x79, 0x52, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e,
+	0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x3a, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f,
+	0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13,
+	0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74,
+	0x69, 0x74, 0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69,
+	0x74, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4e,
+	0x61, 0x6d, 0x65, 0x22, 0xe8, 0x02, 0x0a, 0x15, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65,
+	0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x12, 0x33, 0x0a,
+	0x15, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x61, 0x70,
+	0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f,
+	0x6c, 0x73, 0x12, 0x3d, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65,
+	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73, 0x32,
+	0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69,
+	0x6f, 0x6e, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x54, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+	0x6e, 0x12, 0x3d, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65, 0x72,
+	0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73, 0x32, 0x61,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+	0x6e, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x54, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+	0x12, 0x41, 0x0a, 0x10, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75,
+	0x69, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x73, 0x32, 0x61,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69,
+	0x74, 0x65, 0x52, 0x0f, 0x74, 0x6c, 0x73, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69,
+	0x74, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x10, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x65,
+	0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e,
+	0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69,
+	0x74, 0x79, 0x52, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
+	0x69, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x6e, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18,
+	0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x69, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x2b,
+	0x0a, 0x0e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71,
+	0x12, 0x19, 0x0a, 0x08, 0x69, 0x6e, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x07, 0x69, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x13,
+	0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74,
+	0x52, 0x65, 0x71, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x6e, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18,
+	0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x69, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x23,
+	0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
+	0x6e, 0x49, 0x64, 0x12, 0x3a, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x65,
+	0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32,
+	0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
+	0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22,
+	0xf4, 0x02, 0x0a, 0x0a, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x45,
+	0x0a, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
+	0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+	0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x45, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f,
+	0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x32,
+	0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65,
+	0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52,
+	0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2f, 0x0a, 0x04,
+	0x6e, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x32, 0x61,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x65,
+	0x78, 0x74, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x65, 0x78, 0x74, 0x12, 0x4d, 0x0a,
+	0x11, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x63, 0x6b,
+	0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54,
+	0x69, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x10, 0x72, 0x65, 0x73, 0x75,
+	0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x4b, 0x0a, 0x0f,
+	0x61, 0x75, 0x74, 0x68, 0x5f, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x73, 0x18,
+	0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x4d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x4d,
+	0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x72, 0x65, 0x71,
+	0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0xa0, 0x03, 0x0a, 0x0c, 0x53, 0x65, 0x73, 0x73, 0x69,
+	0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x36, 0x0a, 0x0b, 0x74, 0x6c, 0x73, 0x5f, 0x76,
+	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73,
+	0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73,
+	0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x74, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
+	0x3f, 0x0a, 0x0f, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69,
+	0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, 0x74, 0x65,
+	0x52, 0x0e, 0x74, 0x6c, 0x73, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, 0x74, 0x65,
+	0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x69, 0x6e, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
+	0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
+	0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x71, 0x75,
+	0x65, 0x6e, 0x63, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x69, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05,
+	0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x6f,
+	0x75, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x75,
+	0x74, 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x69, 0x6e, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64,
+	0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x69, 0x6e,
+	0x46, 0x69, 0x78, 0x65, 0x64, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x6f, 0x75,
+	0x74, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x08, 0x20,
+	0x01, 0x28, 0x0c, 0x52, 0x0d, 0x6f, 0x75, 0x74, 0x46, 0x69, 0x78, 0x65, 0x64, 0x4e, 0x6f, 0x6e,
+	0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+	0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
+	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x73, 0x5f, 0x68, 0x61,
+	0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x18,
+	0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x73, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61,
+	0x6b, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x22, 0xd1, 0x02, 0x0a, 0x0d, 0x53, 0x65,
+	0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x31, 0x0a, 0x14, 0x61,
+	0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x61, 0x70, 0x70, 0x6c, 0x69,
+	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x2d,
+	0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
+	0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
+	0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x38, 0x0a,
+	0x0d, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0c, 0x70, 0x65, 0x65, 0x72, 0x49,
+	0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x3a, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
+	0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e,
+	0x74, 0x69, 0x74, 0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74,
+	0x69, 0x74, 0x79, 0x12, 0x34, 0x0a, 0x16, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x65, 0x72,
+	0x74, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x06, 0x20,
+	0x01, 0x28, 0x0c, 0x52, 0x14, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x65, 0x72, 0x74, 0x46, 0x69,
+	0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x65, 0x65,
+	0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+	0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, 0x65, 0x65, 0x72, 0x43, 0x65,
+	0x72, 0x74, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x22, 0x3d, 0x0a,
+	0x0d, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12,
+	0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f,
+	0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0xf3, 0x01, 0x0a,
+	0x0b, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3a, 0x0a, 0x0e,
+	0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
+	0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f,
+	0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75,
+	0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x79, 0x74, 0x65, 0x73,
+	0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52,
+	0x0d, 0x62, 0x79, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x12, 0x30,
+	0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18,
+	0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69,
+	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74,
+	0x12, 0x30, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x18, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x73,
+	0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74,
+	0x75, 0x73, 0x32, 0x51, 0x0a, 0x0a, 0x53, 0x32, 0x41, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x12, 0x43, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x55, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
+	0x12, 0x15, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x73,
+	0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22,
+	0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
+	0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x73, 0x32, 0x61, 0x2f, 0x69,
+	0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x32,
+	0x61, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x33,
+}
+
+var (
+	file_internal_proto_s2a_s2a_proto_rawDescOnce sync.Once
+	file_internal_proto_s2a_s2a_proto_rawDescData = file_internal_proto_s2a_s2a_proto_rawDesc
+)
+
+func file_internal_proto_s2a_s2a_proto_rawDescGZIP() []byte {
+	file_internal_proto_s2a_s2a_proto_rawDescOnce.Do(func() {
+		file_internal_proto_s2a_s2a_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_s2a_s2a_proto_rawDescData)
+	})
+	return file_internal_proto_s2a_s2a_proto_rawDescData
+}
+
+var file_internal_proto_s2a_s2a_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
+var file_internal_proto_s2a_s2a_proto_goTypes = []interface{}{
+	(*AuthenticationMechanism)(nil),  // 0: s2a.proto.AuthenticationMechanism
+	(*ClientSessionStartReq)(nil),    // 1: s2a.proto.ClientSessionStartReq
+	(*ServerSessionStartReq)(nil),    // 2: s2a.proto.ServerSessionStartReq
+	(*SessionNextReq)(nil),           // 3: s2a.proto.SessionNextReq
+	(*ResumptionTicketReq)(nil),      // 4: s2a.proto.ResumptionTicketReq
+	(*SessionReq)(nil),               // 5: s2a.proto.SessionReq
+	(*SessionState)(nil),             // 6: s2a.proto.SessionState
+	(*SessionResult)(nil),            // 7: s2a.proto.SessionResult
+	(*SessionStatus)(nil),            // 8: s2a.proto.SessionStatus
+	(*SessionResp)(nil),              // 9: s2a.proto.SessionResp
+	(*common_go_proto.Identity)(nil), // 10: s2a.proto.Identity
+	(common_go_proto.TLSVersion)(0),  // 11: s2a.proto.TLSVersion
+	(common_go_proto.Ciphersuite)(0), // 12: s2a.proto.Ciphersuite
+}
+var file_internal_proto_s2a_s2a_proto_depIdxs = []int32{
+	10, // 0: s2a.proto.AuthenticationMechanism.identity:type_name -> s2a.proto.Identity
+	11, // 1: s2a.proto.ClientSessionStartReq.min_tls_version:type_name -> s2a.proto.TLSVersion
+	11, // 2: s2a.proto.ClientSessionStartReq.max_tls_version:type_name -> s2a.proto.TLSVersion
+	12, // 3: s2a.proto.ClientSessionStartReq.tls_ciphersuites:type_name -> s2a.proto.Ciphersuite
+	10, // 4: s2a.proto.ClientSessionStartReq.target_identities:type_name -> s2a.proto.Identity
+	10, // 5: s2a.proto.ClientSessionStartReq.local_identity:type_name -> s2a.proto.Identity
+	11, // 6: s2a.proto.ServerSessionStartReq.min_tls_version:type_name -> s2a.proto.TLSVersion
+	11, // 7: s2a.proto.ServerSessionStartReq.max_tls_version:type_name -> s2a.proto.TLSVersion
+	12, // 8: s2a.proto.ServerSessionStartReq.tls_ciphersuites:type_name -> s2a.proto.Ciphersuite
+	10, // 9: s2a.proto.ServerSessionStartReq.local_identities:type_name -> s2a.proto.Identity
+	10, // 10: s2a.proto.ResumptionTicketReq.local_identity:type_name -> s2a.proto.Identity
+	1,  // 11: s2a.proto.SessionReq.client_start:type_name -> s2a.proto.ClientSessionStartReq
+	2,  // 12: s2a.proto.SessionReq.server_start:type_name -> s2a.proto.ServerSessionStartReq
+	3,  // 13: s2a.proto.SessionReq.next:type_name -> s2a.proto.SessionNextReq
+	4,  // 14: s2a.proto.SessionReq.resumption_ticket:type_name -> s2a.proto.ResumptionTicketReq
+	0,  // 15: s2a.proto.SessionReq.auth_mechanisms:type_name -> s2a.proto.AuthenticationMechanism
+	11, // 16: s2a.proto.SessionState.tls_version:type_name -> s2a.proto.TLSVersion
+	12, // 17: s2a.proto.SessionState.tls_ciphersuite:type_name -> s2a.proto.Ciphersuite
+	6,  // 18: s2a.proto.SessionResult.state:type_name -> s2a.proto.SessionState
+	10, // 19: s2a.proto.SessionResult.peer_identity:type_name -> s2a.proto.Identity
+	10, // 20: s2a.proto.SessionResult.local_identity:type_name -> s2a.proto.Identity
+	10, // 21: s2a.proto.SessionResp.local_identity:type_name -> s2a.proto.Identity
+	7,  // 22: s2a.proto.SessionResp.result:type_name -> s2a.proto.SessionResult
+	8,  // 23: s2a.proto.SessionResp.status:type_name -> s2a.proto.SessionStatus
+	5,  // 24: s2a.proto.S2AService.SetUpSession:input_type -> s2a.proto.SessionReq
+	9,  // 25: s2a.proto.S2AService.SetUpSession:output_type -> s2a.proto.SessionResp
+	25, // [25:26] is the sub-list for method output_type
+	24, // [24:25] is the sub-list for method input_type
+	24, // [24:24] is the sub-list for extension type_name
+	24, // [24:24] is the sub-list for extension extendee
+	0,  // [0:24] is the sub-list for field type_name
+}
+
+func init() { file_internal_proto_s2a_s2a_proto_init() }
+func file_internal_proto_s2a_s2a_proto_init() {
+	if File_internal_proto_s2a_s2a_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_internal_proto_s2a_s2a_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AuthenticationMechanism); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_s2a_s2a_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ClientSessionStartReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_s2a_s2a_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ServerSessionStartReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_s2a_s2a_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SessionNextReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_s2a_s2a_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ResumptionTicketReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_s2a_s2a_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SessionReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_s2a_s2a_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SessionState); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_s2a_s2a_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SessionResult); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_s2a_s2a_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SessionStatus); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_s2a_s2a_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SessionResp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	file_internal_proto_s2a_s2a_proto_msgTypes[0].OneofWrappers = []interface{}{
+		(*AuthenticationMechanism_Token)(nil),
+	}
+	file_internal_proto_s2a_s2a_proto_msgTypes[5].OneofWrappers = []interface{}{
+		(*SessionReq_ClientStart)(nil),
+		(*SessionReq_ServerStart)(nil),
+		(*SessionReq_Next)(nil),
+		(*SessionReq_ResumptionTicket)(nil),
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_internal_proto_s2a_s2a_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   10,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_internal_proto_s2a_s2a_proto_goTypes,
+		DependencyIndexes: file_internal_proto_s2a_s2a_proto_depIdxs,
+		MessageInfos:      file_internal_proto_s2a_s2a_proto_msgTypes,
+	}.Build()
+	File_internal_proto_s2a_s2a_proto = out.File
+	file_internal_proto_s2a_s2a_proto_rawDesc = nil
+	file_internal_proto_s2a_s2a_proto_goTypes = nil
+	file_internal_proto_s2a_s2a_proto_depIdxs = nil
+}

+ 173 - 0
vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a_grpc.pb.go

@@ -0,0 +1,173 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.3.0
+// - protoc             v3.21.12
+// source: internal/proto/s2a/s2a.proto
+
+package s2a_go_proto
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.32.0 or later.
+const _ = grpc.SupportPackageIsVersion7
+
+const (
+	S2AService_SetUpSession_FullMethodName = "/s2a.proto.S2AService/SetUpSession"
+)
+
+// S2AServiceClient is the client API for S2AService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type S2AServiceClient interface {
+	// S2A service accepts a stream of session setup requests and returns a stream
+	// of session setup responses. The client of this service is expected to send
+	// exactly one client_start or server_start message followed by at least one
+	// next message. Applications running TLS clients can send requests with
+	// resumption_ticket messages only after the session is successfully set up.
+	//
+	// Every time S2A client sends a request, this service sends a response.
+	// However, clients do not have to wait for service response before sending
+	// the next request.
+	SetUpSession(ctx context.Context, opts ...grpc.CallOption) (S2AService_SetUpSessionClient, error)
+}
+
+type s2AServiceClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewS2AServiceClient(cc grpc.ClientConnInterface) S2AServiceClient {
+	return &s2AServiceClient{cc}
+}
+
+func (c *s2AServiceClient) SetUpSession(ctx context.Context, opts ...grpc.CallOption) (S2AService_SetUpSessionClient, error) {
+	stream, err := c.cc.NewStream(ctx, &S2AService_ServiceDesc.Streams[0], S2AService_SetUpSession_FullMethodName, opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &s2AServiceSetUpSessionClient{stream}
+	return x, nil
+}
+
+type S2AService_SetUpSessionClient interface {
+	Send(*SessionReq) error
+	Recv() (*SessionResp, error)
+	grpc.ClientStream
+}
+
+type s2AServiceSetUpSessionClient struct {
+	grpc.ClientStream
+}
+
+func (x *s2AServiceSetUpSessionClient) Send(m *SessionReq) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *s2AServiceSetUpSessionClient) Recv() (*SessionResp, error) {
+	m := new(SessionResp)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+// S2AServiceServer is the server API for S2AService service.
+// All implementations must embed UnimplementedS2AServiceServer
+// for forward compatibility
+type S2AServiceServer interface {
+	// S2A service accepts a stream of session setup requests and returns a stream
+	// of session setup responses. The client of this service is expected to send
+	// exactly one client_start or server_start message followed by at least one
+	// next message. Applications running TLS clients can send requests with
+	// resumption_ticket messages only after the session is successfully set up.
+	//
+	// Every time S2A client sends a request, this service sends a response.
+	// However, clients do not have to wait for service response before sending
+	// the next request.
+	SetUpSession(S2AService_SetUpSessionServer) error
+	mustEmbedUnimplementedS2AServiceServer()
+}
+
+// UnimplementedS2AServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedS2AServiceServer struct {
+}
+
+func (UnimplementedS2AServiceServer) SetUpSession(S2AService_SetUpSessionServer) error {
+	return status.Errorf(codes.Unimplemented, "method SetUpSession not implemented")
+}
+func (UnimplementedS2AServiceServer) mustEmbedUnimplementedS2AServiceServer() {}
+
+// UnsafeS2AServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to S2AServiceServer will
+// result in compilation errors.
+type UnsafeS2AServiceServer interface {
+	mustEmbedUnimplementedS2AServiceServer()
+}
+
+func RegisterS2AServiceServer(s grpc.ServiceRegistrar, srv S2AServiceServer) {
+	s.RegisterService(&S2AService_ServiceDesc, srv)
+}
+
+func _S2AService_SetUpSession_Handler(srv interface{}, stream grpc.ServerStream) error {
+	return srv.(S2AServiceServer).SetUpSession(&s2AServiceSetUpSessionServer{stream})
+}
+
+type S2AService_SetUpSessionServer interface {
+	Send(*SessionResp) error
+	Recv() (*SessionReq, error)
+	grpc.ServerStream
+}
+
+type s2AServiceSetUpSessionServer struct {
+	grpc.ServerStream
+}
+
+func (x *s2AServiceSetUpSessionServer) Send(m *SessionResp) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *s2AServiceSetUpSessionServer) Recv() (*SessionReq, error) {
+	m := new(SessionReq)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+// S2AService_ServiceDesc is the grpc.ServiceDesc for S2AService service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var S2AService_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "s2a.proto.S2AService",
+	HandlerType: (*S2AServiceServer)(nil),
+	Methods:     []grpc.MethodDesc{},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "SetUpSession",
+			Handler:       _S2AService_SetUpSession_Handler,
+			ServerStreams: true,
+			ClientStreams: true,
+		},
+	},
+	Metadata: "internal/proto/s2a/s2a.proto",
+}

+ 367 - 0
vendor/github.com/google/s2a-go/internal/proto/v2/common_go_proto/common.pb.go

@@ -0,0 +1,367 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.30.0
+// 	protoc        v3.21.12
+// source: internal/proto/v2/common/common.proto
+
+package common_go_proto
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// The TLS 1.0-1.2 ciphersuites that the application can negotiate when using
+// S2A.
+type Ciphersuite int32
+
+const (
+	Ciphersuite_CIPHERSUITE_UNSPECIFIED                               Ciphersuite = 0
+	Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256       Ciphersuite = 1
+	Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384       Ciphersuite = 2
+	Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 Ciphersuite = 3
+	Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256         Ciphersuite = 4
+	Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384         Ciphersuite = 5
+	Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256   Ciphersuite = 6
+)
+
+// Enum value maps for Ciphersuite.
+var (
+	Ciphersuite_name = map[int32]string{
+		0: "CIPHERSUITE_UNSPECIFIED",
+		1: "CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+		2: "CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+		3: "CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+		4: "CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+		5: "CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+		6: "CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+	}
+	Ciphersuite_value = map[string]int32{
+		"CIPHERSUITE_UNSPECIFIED":                               0,
+		"CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256":       1,
+		"CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384":       2,
+		"CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256": 3,
+		"CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256":         4,
+		"CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384":         5,
+		"CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256":   6,
+	}
+)
+
+func (x Ciphersuite) Enum() *Ciphersuite {
+	p := new(Ciphersuite)
+	*p = x
+	return p
+}
+
+func (x Ciphersuite) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Ciphersuite) Descriptor() protoreflect.EnumDescriptor {
+	return file_internal_proto_v2_common_common_proto_enumTypes[0].Descriptor()
+}
+
+func (Ciphersuite) Type() protoreflect.EnumType {
+	return &file_internal_proto_v2_common_common_proto_enumTypes[0]
+}
+
+func (x Ciphersuite) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Ciphersuite.Descriptor instead.
+func (Ciphersuite) EnumDescriptor() ([]byte, []int) {
+	return file_internal_proto_v2_common_common_proto_rawDescGZIP(), []int{0}
+}
+
+// The TLS versions supported by S2A's handshaker module.
+type TLSVersion int32
+
+const (
+	TLSVersion_TLS_VERSION_UNSPECIFIED TLSVersion = 0
+	TLSVersion_TLS_VERSION_1_0         TLSVersion = 1
+	TLSVersion_TLS_VERSION_1_1         TLSVersion = 2
+	TLSVersion_TLS_VERSION_1_2         TLSVersion = 3
+	TLSVersion_TLS_VERSION_1_3         TLSVersion = 4
+)
+
+// Enum value maps for TLSVersion.
+var (
+	TLSVersion_name = map[int32]string{
+		0: "TLS_VERSION_UNSPECIFIED",
+		1: "TLS_VERSION_1_0",
+		2: "TLS_VERSION_1_1",
+		3: "TLS_VERSION_1_2",
+		4: "TLS_VERSION_1_3",
+	}
+	TLSVersion_value = map[string]int32{
+		"TLS_VERSION_UNSPECIFIED": 0,
+		"TLS_VERSION_1_0":         1,
+		"TLS_VERSION_1_1":         2,
+		"TLS_VERSION_1_2":         3,
+		"TLS_VERSION_1_3":         4,
+	}
+)
+
+func (x TLSVersion) Enum() *TLSVersion {
+	p := new(TLSVersion)
+	*p = x
+	return p
+}
+
+func (x TLSVersion) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (TLSVersion) Descriptor() protoreflect.EnumDescriptor {
+	return file_internal_proto_v2_common_common_proto_enumTypes[1].Descriptor()
+}
+
+func (TLSVersion) Type() protoreflect.EnumType {
+	return &file_internal_proto_v2_common_common_proto_enumTypes[1]
+}
+
+func (x TLSVersion) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use TLSVersion.Descriptor instead.
+func (TLSVersion) EnumDescriptor() ([]byte, []int) {
+	return file_internal_proto_v2_common_common_proto_rawDescGZIP(), []int{1}
+}
+
+// The side in the TLS connection.
+type ConnectionSide int32
+
+const (
+	ConnectionSide_CONNECTION_SIDE_UNSPECIFIED ConnectionSide = 0
+	ConnectionSide_CONNECTION_SIDE_CLIENT      ConnectionSide = 1
+	ConnectionSide_CONNECTION_SIDE_SERVER      ConnectionSide = 2
+)
+
+// Enum value maps for ConnectionSide.
+var (
+	ConnectionSide_name = map[int32]string{
+		0: "CONNECTION_SIDE_UNSPECIFIED",
+		1: "CONNECTION_SIDE_CLIENT",
+		2: "CONNECTION_SIDE_SERVER",
+	}
+	ConnectionSide_value = map[string]int32{
+		"CONNECTION_SIDE_UNSPECIFIED": 0,
+		"CONNECTION_SIDE_CLIENT":      1,
+		"CONNECTION_SIDE_SERVER":      2,
+	}
+)
+
+func (x ConnectionSide) Enum() *ConnectionSide {
+	p := new(ConnectionSide)
+	*p = x
+	return p
+}
+
+func (x ConnectionSide) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ConnectionSide) Descriptor() protoreflect.EnumDescriptor {
+	return file_internal_proto_v2_common_common_proto_enumTypes[2].Descriptor()
+}
+
+func (ConnectionSide) Type() protoreflect.EnumType {
+	return &file_internal_proto_v2_common_common_proto_enumTypes[2]
+}
+
+func (x ConnectionSide) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ConnectionSide.Descriptor instead.
+func (ConnectionSide) EnumDescriptor() ([]byte, []int) {
+	return file_internal_proto_v2_common_common_proto_rawDescGZIP(), []int{2}
+}
+
+// The ALPN protocols that the application can negotiate during a TLS handshake.
+type AlpnProtocol int32
+
+const (
+	AlpnProtocol_ALPN_PROTOCOL_UNSPECIFIED AlpnProtocol = 0
+	AlpnProtocol_ALPN_PROTOCOL_GRPC        AlpnProtocol = 1
+	AlpnProtocol_ALPN_PROTOCOL_HTTP2       AlpnProtocol = 2
+	AlpnProtocol_ALPN_PROTOCOL_HTTP1_1     AlpnProtocol = 3
+)
+
+// Enum value maps for AlpnProtocol.
+var (
+	AlpnProtocol_name = map[int32]string{
+		0: "ALPN_PROTOCOL_UNSPECIFIED",
+		1: "ALPN_PROTOCOL_GRPC",
+		2: "ALPN_PROTOCOL_HTTP2",
+		3: "ALPN_PROTOCOL_HTTP1_1",
+	}
+	AlpnProtocol_value = map[string]int32{
+		"ALPN_PROTOCOL_UNSPECIFIED": 0,
+		"ALPN_PROTOCOL_GRPC":        1,
+		"ALPN_PROTOCOL_HTTP2":       2,
+		"ALPN_PROTOCOL_HTTP1_1":     3,
+	}
+)
+
+func (x AlpnProtocol) Enum() *AlpnProtocol {
+	p := new(AlpnProtocol)
+	*p = x
+	return p
+}
+
+func (x AlpnProtocol) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (AlpnProtocol) Descriptor() protoreflect.EnumDescriptor {
+	return file_internal_proto_v2_common_common_proto_enumTypes[3].Descriptor()
+}
+
+func (AlpnProtocol) Type() protoreflect.EnumType {
+	return &file_internal_proto_v2_common_common_proto_enumTypes[3]
+}
+
+func (x AlpnProtocol) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use AlpnProtocol.Descriptor instead.
+func (AlpnProtocol) EnumDescriptor() ([]byte, []int) {
+	return file_internal_proto_v2_common_common_proto_rawDescGZIP(), []int{3}
+}
+
+var File_internal_proto_v2_common_common_proto protoreflect.FileDescriptor
+
+var file_internal_proto_v2_common_common_proto_rawDesc = []byte{
+	0x0a, 0x25, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
+	0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2a, 0xee, 0x02, 0x0a, 0x0b, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72,
+	0x73, 0x75, 0x69, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x53,
+	0x55, 0x49, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44,
+	0x10, 0x00, 0x12, 0x33, 0x0a, 0x2f, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x53, 0x55, 0x49, 0x54,
+	0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x57, 0x49,
+	0x54, 0x48, 0x5f, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43, 0x4d, 0x5f, 0x53,
+	0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x01, 0x12, 0x33, 0x0a, 0x2f, 0x43, 0x49, 0x50, 0x48, 0x45,
+	0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x45, 0x43, 0x44,
+	0x53, 0x41, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f,
+	0x47, 0x43, 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x02, 0x12, 0x39, 0x0a, 0x35,
+	0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48,
+	0x45, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x43, 0x48, 0x41,
+	0x43, 0x48, 0x41, 0x32, 0x30, 0x5f, 0x50, 0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, 0x35, 0x5f, 0x53,
+	0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x03, 0x12, 0x31, 0x0a, 0x2d, 0x43, 0x49, 0x50, 0x48, 0x45,
+	0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x52, 0x53, 0x41,
+	0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43,
+	0x4d, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x04, 0x12, 0x31, 0x0a, 0x2d, 0x43, 0x49,
+	0x50, 0x48, 0x45, 0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f,
+	0x52, 0x53, 0x41, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36,
+	0x5f, 0x47, 0x43, 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x05, 0x12, 0x37, 0x0a,
+	0x33, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44,
+	0x48, 0x45, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x43, 0x48, 0x41, 0x43,
+	0x48, 0x41, 0x32, 0x30, 0x5f, 0x50, 0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, 0x35, 0x5f, 0x53, 0x48,
+	0x41, 0x32, 0x35, 0x36, 0x10, 0x06, 0x2a, 0x7d, 0x0a, 0x0a, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72,
+	0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53,
+	0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
+	0x00, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e,
+	0x5f, 0x31, 0x5f, 0x30, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45,
+	0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x5f, 0x31, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x54,
+	0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x5f, 0x32, 0x10, 0x03,
+	0x12, 0x13, 0x0a, 0x0f, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f,
+	0x31, 0x5f, 0x33, 0x10, 0x04, 0x2a, 0x69, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
+	0x69, 0x6f, 0x6e, 0x53, 0x69, 0x64, 0x65, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x4e, 0x4e, 0x45,
+	0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45,
+	0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4e, 0x4e,
+	0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x44, 0x45, 0x5f, 0x43, 0x4c, 0x49, 0x45,
+	0x4e, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49,
+	0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x44, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x02,
+	0x2a, 0x79, 0x0a, 0x0c, 0x41, 0x6c, 0x70, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
+	0x12, 0x1d, 0x0a, 0x19, 0x41, 0x4c, 0x50, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f,
+	0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
+	0x16, 0x0a, 0x12, 0x41, 0x4c, 0x50, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c,
+	0x5f, 0x47, 0x52, 0x50, 0x43, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x4c, 0x50, 0x4e, 0x5f,
+	0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x32, 0x10, 0x02,
+	0x12, 0x19, 0x0a, 0x15, 0x41, 0x4c, 0x50, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f,
+	0x4c, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x31, 0x5f, 0x31, 0x10, 0x03, 0x42, 0x39, 0x5a, 0x37, 0x67,
+	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2f, 0x73, 0x32, 0x61, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x67, 0x6f,
+	0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_internal_proto_v2_common_common_proto_rawDescOnce sync.Once
+	file_internal_proto_v2_common_common_proto_rawDescData = file_internal_proto_v2_common_common_proto_rawDesc
+)
+
+func file_internal_proto_v2_common_common_proto_rawDescGZIP() []byte {
+	file_internal_proto_v2_common_common_proto_rawDescOnce.Do(func() {
+		file_internal_proto_v2_common_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_v2_common_common_proto_rawDescData)
+	})
+	return file_internal_proto_v2_common_common_proto_rawDescData
+}
+
+var file_internal_proto_v2_common_common_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
+var file_internal_proto_v2_common_common_proto_goTypes = []interface{}{
+	(Ciphersuite)(0),    // 0: s2a.proto.v2.Ciphersuite
+	(TLSVersion)(0),     // 1: s2a.proto.v2.TLSVersion
+	(ConnectionSide)(0), // 2: s2a.proto.v2.ConnectionSide
+	(AlpnProtocol)(0),   // 3: s2a.proto.v2.AlpnProtocol
+}
+var file_internal_proto_v2_common_common_proto_depIdxs = []int32{
+	0, // [0:0] is the sub-list for method output_type
+	0, // [0:0] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_internal_proto_v2_common_common_proto_init() }
+func file_internal_proto_v2_common_common_proto_init() {
+	if File_internal_proto_v2_common_common_proto != nil {
+		return
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_internal_proto_v2_common_common_proto_rawDesc,
+			NumEnums:      4,
+			NumMessages:   0,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_internal_proto_v2_common_common_proto_goTypes,
+		DependencyIndexes: file_internal_proto_v2_common_common_proto_depIdxs,
+		EnumInfos:         file_internal_proto_v2_common_common_proto_enumTypes,
+	}.Build()
+	File_internal_proto_v2_common_common_proto = out.File
+	file_internal_proto_v2_common_common_proto_rawDesc = nil
+	file_internal_proto_v2_common_common_proto_goTypes = nil
+	file_internal_proto_v2_common_common_proto_depIdxs = nil
+}

+ 248 - 0
vendor/github.com/google/s2a-go/internal/proto/v2/s2a_context_go_proto/s2a_context.pb.go

@@ -0,0 +1,248 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.30.0
+// 	protoc        v3.21.12
+// source: internal/proto/v2/s2a_context/s2a_context.proto
+
+package s2a_context_go_proto
+
+import (
+	common_go_proto "github.com/google/s2a-go/internal/proto/common_go_proto"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type S2AContext struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The SPIFFE ID from the peer leaf certificate, if present.
+	//
+	// This field is only populated if the leaf certificate is a valid SPIFFE
+	// SVID; in particular, there is a unique URI SAN and this URI SAN is a valid
+	// SPIFFE ID.
+	LeafCertSpiffeId string `protobuf:"bytes,1,opt,name=leaf_cert_spiffe_id,json=leafCertSpiffeId,proto3" json:"leaf_cert_spiffe_id,omitempty"`
+	// The URIs that are present in the SubjectAltName extension of the peer leaf
+	// certificate.
+	//
+	// Note that the extracted URIs are not validated and may not be properly
+	// formatted.
+	LeafCertUris []string `protobuf:"bytes,2,rep,name=leaf_cert_uris,json=leafCertUris,proto3" json:"leaf_cert_uris,omitempty"`
+	// The DNSNames that are present in the SubjectAltName extension of the peer
+	// leaf certificate.
+	LeafCertDnsnames []string `protobuf:"bytes,3,rep,name=leaf_cert_dnsnames,json=leafCertDnsnames,proto3" json:"leaf_cert_dnsnames,omitempty"`
+	// The (ordered) list of fingerprints in the certificate chain used to verify
+	// the given leaf certificate. The order MUST be from leaf certificate
+	// fingerprint to root certificate fingerprint.
+	//
+	// A fingerprint is the base-64 encoding of the SHA256 hash of the
+	// DER-encoding of a certificate. The list MAY be populated even if the peer
+	// certificate chain was NOT validated successfully.
+	PeerCertificateChainFingerprints []string `protobuf:"bytes,4,rep,name=peer_certificate_chain_fingerprints,json=peerCertificateChainFingerprints,proto3" json:"peer_certificate_chain_fingerprints,omitempty"`
+	// The local identity used during session setup.
+	LocalIdentity *common_go_proto.Identity `protobuf:"bytes,5,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"`
+	// The SHA256 hash of the DER-encoding of the local leaf certificate used in
+	// the handshake.
+	LocalLeafCertFingerprint []byte `protobuf:"bytes,6,opt,name=local_leaf_cert_fingerprint,json=localLeafCertFingerprint,proto3" json:"local_leaf_cert_fingerprint,omitempty"`
+}
+
+func (x *S2AContext) Reset() {
+	*x = S2AContext{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *S2AContext) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*S2AContext) ProtoMessage() {}
+
+func (x *S2AContext) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use S2AContext.ProtoReflect.Descriptor instead.
+func (*S2AContext) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *S2AContext) GetLeafCertSpiffeId() string {
+	if x != nil {
+		return x.LeafCertSpiffeId
+	}
+	return ""
+}
+
+func (x *S2AContext) GetLeafCertUris() []string {
+	if x != nil {
+		return x.LeafCertUris
+	}
+	return nil
+}
+
+func (x *S2AContext) GetLeafCertDnsnames() []string {
+	if x != nil {
+		return x.LeafCertDnsnames
+	}
+	return nil
+}
+
+func (x *S2AContext) GetPeerCertificateChainFingerprints() []string {
+	if x != nil {
+		return x.PeerCertificateChainFingerprints
+	}
+	return nil
+}
+
+func (x *S2AContext) GetLocalIdentity() *common_go_proto.Identity {
+	if x != nil {
+		return x.LocalIdentity
+	}
+	return nil
+}
+
+func (x *S2AContext) GetLocalLeafCertFingerprint() []byte {
+	if x != nil {
+		return x.LocalLeafCertFingerprint
+	}
+	return nil
+}
+
+var File_internal_proto_v2_s2a_context_s2a_context_proto protoreflect.FileDescriptor
+
+var file_internal_proto_v2_s2a_context_s2a_context_proto_rawDesc = []byte{
+	0x0a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2f, 0x76, 0x32, 0x2f, 0x73, 0x32, 0x61, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2f,
+	0x73, 0x32, 0x61, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x12, 0x0c, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x1a,
+	0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f,
+	0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x22, 0xd9, 0x02, 0x0a, 0x0a, 0x53, 0x32, 0x41, 0x43, 0x6f, 0x6e, 0x74, 0x65,
+	0x78, 0x74, 0x12, 0x2d, 0x0a, 0x13, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f,
+	0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x10, 0x6c, 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x49,
+	0x64, 0x12, 0x24, 0x0a, 0x0e, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x75,
+	0x72, 0x69, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6c, 0x65, 0x61, 0x66, 0x43,
+	0x65, 0x72, 0x74, 0x55, 0x72, 0x69, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x65, 0x61, 0x66, 0x5f,
+	0x63, 0x65, 0x72, 0x74, 0x5f, 0x64, 0x6e, 0x73, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20,
+	0x03, 0x28, 0x09, 0x52, 0x10, 0x6c, 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, 0x44, 0x6e, 0x73,
+	0x6e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x23, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63, 0x65,
+	0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f,
+	0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03,
+	0x28, 0x09, 0x52, 0x20, 0x70, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+	0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+	0x69, 0x6e, 0x74, 0x73, 0x12, 0x3a, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64,
+	0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73,
+	0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
+	0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
+	0x12, 0x3d, 0x0a, 0x1b, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x63,
+	0x65, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18,
+	0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x18, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x4c, 0x65, 0x61, 0x66,
+	0x43, 0x65, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x42,
+	0x3e, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f,
+	0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x73, 0x32, 0x61, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
+	0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x32, 0x61, 0x5f, 0x63,
+	0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescOnce sync.Once
+	file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescData = file_internal_proto_v2_s2a_context_s2a_context_proto_rawDesc
+)
+
+func file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescGZIP() []byte {
+	file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescOnce.Do(func() {
+		file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescData)
+	})
+	return file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescData
+}
+
+var file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_internal_proto_v2_s2a_context_s2a_context_proto_goTypes = []interface{}{
+	(*S2AContext)(nil),               // 0: s2a.proto.v2.S2AContext
+	(*common_go_proto.Identity)(nil), // 1: s2a.proto.Identity
+}
+var file_internal_proto_v2_s2a_context_s2a_context_proto_depIdxs = []int32{
+	1, // 0: s2a.proto.v2.S2AContext.local_identity:type_name -> s2a.proto.Identity
+	1, // [1:1] is the sub-list for method output_type
+	1, // [1:1] is the sub-list for method input_type
+	1, // [1:1] is the sub-list for extension type_name
+	1, // [1:1] is the sub-list for extension extendee
+	0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_internal_proto_v2_s2a_context_s2a_context_proto_init() }
+func file_internal_proto_v2_s2a_context_s2a_context_proto_init() {
+	if File_internal_proto_v2_s2a_context_s2a_context_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*S2AContext); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_internal_proto_v2_s2a_context_s2a_context_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   1,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_internal_proto_v2_s2a_context_s2a_context_proto_goTypes,
+		DependencyIndexes: file_internal_proto_v2_s2a_context_s2a_context_proto_depIdxs,
+		MessageInfos:      file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes,
+	}.Build()
+	File_internal_proto_v2_s2a_context_s2a_context_proto = out.File
+	file_internal_proto_v2_s2a_context_s2a_context_proto_rawDesc = nil
+	file_internal_proto_v2_s2a_context_s2a_context_proto_goTypes = nil
+	file_internal_proto_v2_s2a_context_s2a_context_proto_depIdxs = nil
+}

+ 2494 - 0
vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a.pb.go

@@ -0,0 +1,2494 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.30.0
+// 	protoc        v3.21.12
+// source: internal/proto/v2/s2a/s2a.proto
+
+package s2a_go_proto
+
+import (
+	common_go_proto1 "github.com/google/s2a-go/internal/proto/common_go_proto"
+	common_go_proto "github.com/google/s2a-go/internal/proto/v2/common_go_proto"
+	s2a_context_go_proto "github.com/google/s2a-go/internal/proto/v2/s2a_context_go_proto"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type SignatureAlgorithm int32
+
+const (
+	SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED SignatureAlgorithm = 0
+	// RSA Public-Key Cryptography Standards #1.
+	SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA256 SignatureAlgorithm = 1
+	SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA384 SignatureAlgorithm = 2
+	SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA512 SignatureAlgorithm = 3
+	// ECDSA.
+	SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256 SignatureAlgorithm = 4
+	SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384 SignatureAlgorithm = 5
+	SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512 SignatureAlgorithm = 6
+	// RSA Probabilistic Signature Scheme.
+	SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256 SignatureAlgorithm = 7
+	SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384 SignatureAlgorithm = 8
+	SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512 SignatureAlgorithm = 9
+	// ED25519.
+	SignatureAlgorithm_S2A_SSL_SIGN_ED25519 SignatureAlgorithm = 10
+)
+
+// Enum value maps for SignatureAlgorithm.
+var (
+	SignatureAlgorithm_name = map[int32]string{
+		0:  "S2A_SSL_SIGN_UNSPECIFIED",
+		1:  "S2A_SSL_SIGN_RSA_PKCS1_SHA256",
+		2:  "S2A_SSL_SIGN_RSA_PKCS1_SHA384",
+		3:  "S2A_SSL_SIGN_RSA_PKCS1_SHA512",
+		4:  "S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256",
+		5:  "S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384",
+		6:  "S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512",
+		7:  "S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256",
+		8:  "S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384",
+		9:  "S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512",
+		10: "S2A_SSL_SIGN_ED25519",
+	}
+	SignatureAlgorithm_value = map[string]int32{
+		"S2A_SSL_SIGN_UNSPECIFIED":            0,
+		"S2A_SSL_SIGN_RSA_PKCS1_SHA256":       1,
+		"S2A_SSL_SIGN_RSA_PKCS1_SHA384":       2,
+		"S2A_SSL_SIGN_RSA_PKCS1_SHA512":       3,
+		"S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256": 4,
+		"S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384": 5,
+		"S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512": 6,
+		"S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256":    7,
+		"S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384":    8,
+		"S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512":    9,
+		"S2A_SSL_SIGN_ED25519":                10,
+	}
+)
+
+func (x SignatureAlgorithm) Enum() *SignatureAlgorithm {
+	p := new(SignatureAlgorithm)
+	*p = x
+	return p
+}
+
+func (x SignatureAlgorithm) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (SignatureAlgorithm) Descriptor() protoreflect.EnumDescriptor {
+	return file_internal_proto_v2_s2a_s2a_proto_enumTypes[0].Descriptor()
+}
+
+func (SignatureAlgorithm) Type() protoreflect.EnumType {
+	return &file_internal_proto_v2_s2a_s2a_proto_enumTypes[0]
+}
+
+func (x SignatureAlgorithm) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use SignatureAlgorithm.Descriptor instead.
+func (SignatureAlgorithm) EnumDescriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{0}
+}
+
+type GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate int32
+
+const (
+	GetTlsConfigurationResp_ServerTlsConfiguration_UNSPECIFIED                                            GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate = 0
+	GetTlsConfigurationResp_ServerTlsConfiguration_DONT_REQUEST_CLIENT_CERTIFICATE                        GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate = 1
+	GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY             GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate = 2
+	GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY                  GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate = 3
+	GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate = 4
+	GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY      GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate = 5
+)
+
+// Enum value maps for GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate.
+var (
+	GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate_name = map[int32]string{
+		0: "UNSPECIFIED",
+		1: "DONT_REQUEST_CLIENT_CERTIFICATE",
+		2: "REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY",
+		3: "REQUEST_CLIENT_CERTIFICATE_AND_VERIFY",
+		4: "REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY",
+		5: "REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY",
+	}
+	GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate_value = map[string]int32{
+		"UNSPECIFIED":                                            0,
+		"DONT_REQUEST_CLIENT_CERTIFICATE":                        1,
+		"REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY":             2,
+		"REQUEST_CLIENT_CERTIFICATE_AND_VERIFY":                  3,
+		"REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY": 4,
+		"REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY":      5,
+	}
+)
+
+func (x GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate) Enum() *GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate {
+	p := new(GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate)
+	*p = x
+	return p
+}
+
+func (x GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate) Descriptor() protoreflect.EnumDescriptor {
+	return file_internal_proto_v2_s2a_s2a_proto_enumTypes[1].Descriptor()
+}
+
+func (GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate) Type() protoreflect.EnumType {
+	return &file_internal_proto_v2_s2a_s2a_proto_enumTypes[1]
+}
+
+func (x GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate.Descriptor instead.
+func (GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate) EnumDescriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{4, 1, 0}
+}
+
+type OffloadPrivateKeyOperationReq_PrivateKeyOperation int32
+
+const (
+	OffloadPrivateKeyOperationReq_UNSPECIFIED OffloadPrivateKeyOperationReq_PrivateKeyOperation = 0
+	// When performing a TLS 1.2 or 1.3 handshake, the (partial) transcript of
+	// the TLS handshake must be signed to prove possession of the private key.
+	//
+	// See https://www.rfc-editor.org/rfc/rfc8446.html#section-4.4.3.
+	OffloadPrivateKeyOperationReq_SIGN OffloadPrivateKeyOperationReq_PrivateKeyOperation = 1
+	// When performing a TLS 1.2 handshake using an RSA algorithm, the key
+	// exchange algorithm involves the client generating a premaster secret,
+	// encrypting it using the server's public key, and sending this encrypted
+	// blob to the server in a ClientKeyExchange message.
+	//
+	// See https://www.rfc-editor.org/rfc/rfc4346#section-7.4.7.1.
+	OffloadPrivateKeyOperationReq_DECRYPT OffloadPrivateKeyOperationReq_PrivateKeyOperation = 2
+)
+
+// Enum value maps for OffloadPrivateKeyOperationReq_PrivateKeyOperation.
+var (
+	OffloadPrivateKeyOperationReq_PrivateKeyOperation_name = map[int32]string{
+		0: "UNSPECIFIED",
+		1: "SIGN",
+		2: "DECRYPT",
+	}
+	OffloadPrivateKeyOperationReq_PrivateKeyOperation_value = map[string]int32{
+		"UNSPECIFIED": 0,
+		"SIGN":        1,
+		"DECRYPT":     2,
+	}
+)
+
+func (x OffloadPrivateKeyOperationReq_PrivateKeyOperation) Enum() *OffloadPrivateKeyOperationReq_PrivateKeyOperation {
+	p := new(OffloadPrivateKeyOperationReq_PrivateKeyOperation)
+	*p = x
+	return p
+}
+
+func (x OffloadPrivateKeyOperationReq_PrivateKeyOperation) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (OffloadPrivateKeyOperationReq_PrivateKeyOperation) Descriptor() protoreflect.EnumDescriptor {
+	return file_internal_proto_v2_s2a_s2a_proto_enumTypes[2].Descriptor()
+}
+
+func (OffloadPrivateKeyOperationReq_PrivateKeyOperation) Type() protoreflect.EnumType {
+	return &file_internal_proto_v2_s2a_s2a_proto_enumTypes[2]
+}
+
+func (x OffloadPrivateKeyOperationReq_PrivateKeyOperation) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use OffloadPrivateKeyOperationReq_PrivateKeyOperation.Descriptor instead.
+func (OffloadPrivateKeyOperationReq_PrivateKeyOperation) EnumDescriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{5, 0}
+}
+
+type OffloadResumptionKeyOperationReq_ResumptionKeyOperation int32
+
+const (
+	OffloadResumptionKeyOperationReq_UNSPECIFIED OffloadResumptionKeyOperationReq_ResumptionKeyOperation = 0
+	OffloadResumptionKeyOperationReq_ENCRYPT     OffloadResumptionKeyOperationReq_ResumptionKeyOperation = 1
+	OffloadResumptionKeyOperationReq_DECRYPT     OffloadResumptionKeyOperationReq_ResumptionKeyOperation = 2
+)
+
+// Enum value maps for OffloadResumptionKeyOperationReq_ResumptionKeyOperation.
+var (
+	OffloadResumptionKeyOperationReq_ResumptionKeyOperation_name = map[int32]string{
+		0: "UNSPECIFIED",
+		1: "ENCRYPT",
+		2: "DECRYPT",
+	}
+	OffloadResumptionKeyOperationReq_ResumptionKeyOperation_value = map[string]int32{
+		"UNSPECIFIED": 0,
+		"ENCRYPT":     1,
+		"DECRYPT":     2,
+	}
+)
+
+func (x OffloadResumptionKeyOperationReq_ResumptionKeyOperation) Enum() *OffloadResumptionKeyOperationReq_ResumptionKeyOperation {
+	p := new(OffloadResumptionKeyOperationReq_ResumptionKeyOperation)
+	*p = x
+	return p
+}
+
+func (x OffloadResumptionKeyOperationReq_ResumptionKeyOperation) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (OffloadResumptionKeyOperationReq_ResumptionKeyOperation) Descriptor() protoreflect.EnumDescriptor {
+	return file_internal_proto_v2_s2a_s2a_proto_enumTypes[3].Descriptor()
+}
+
+func (OffloadResumptionKeyOperationReq_ResumptionKeyOperation) Type() protoreflect.EnumType {
+	return &file_internal_proto_v2_s2a_s2a_proto_enumTypes[3]
+}
+
+func (x OffloadResumptionKeyOperationReq_ResumptionKeyOperation) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use OffloadResumptionKeyOperationReq_ResumptionKeyOperation.Descriptor instead.
+func (OffloadResumptionKeyOperationReq_ResumptionKeyOperation) EnumDescriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{7, 0}
+}
+
+type ValidatePeerCertificateChainReq_VerificationMode int32
+
+const (
+	// The default verification mode supported by S2A.
+	ValidatePeerCertificateChainReq_UNSPECIFIED ValidatePeerCertificateChainReq_VerificationMode = 0
+	// The SPIFFE verification mode selects the set of trusted certificates to
+	// use for path building based on the SPIFFE trust domain in the peer's leaf
+	// certificate.
+	ValidatePeerCertificateChainReq_SPIFFE ValidatePeerCertificateChainReq_VerificationMode = 1
+	// The connect-to-Google verification mode uses the trust bundle for
+	// connecting to Google, e.g. *.mtls.googleapis.com endpoints.
+	ValidatePeerCertificateChainReq_CONNECT_TO_GOOGLE ValidatePeerCertificateChainReq_VerificationMode = 2
+)
+
+// Enum value maps for ValidatePeerCertificateChainReq_VerificationMode.
+var (
+	ValidatePeerCertificateChainReq_VerificationMode_name = map[int32]string{
+		0: "UNSPECIFIED",
+		1: "SPIFFE",
+		2: "CONNECT_TO_GOOGLE",
+	}
+	ValidatePeerCertificateChainReq_VerificationMode_value = map[string]int32{
+		"UNSPECIFIED":       0,
+		"SPIFFE":            1,
+		"CONNECT_TO_GOOGLE": 2,
+	}
+)
+
+func (x ValidatePeerCertificateChainReq_VerificationMode) Enum() *ValidatePeerCertificateChainReq_VerificationMode {
+	p := new(ValidatePeerCertificateChainReq_VerificationMode)
+	*p = x
+	return p
+}
+
+func (x ValidatePeerCertificateChainReq_VerificationMode) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ValidatePeerCertificateChainReq_VerificationMode) Descriptor() protoreflect.EnumDescriptor {
+	return file_internal_proto_v2_s2a_s2a_proto_enumTypes[4].Descriptor()
+}
+
+func (ValidatePeerCertificateChainReq_VerificationMode) Type() protoreflect.EnumType {
+	return &file_internal_proto_v2_s2a_s2a_proto_enumTypes[4]
+}
+
+func (x ValidatePeerCertificateChainReq_VerificationMode) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ValidatePeerCertificateChainReq_VerificationMode.Descriptor instead.
+func (ValidatePeerCertificateChainReq_VerificationMode) EnumDescriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{9, 0}
+}
+
+type ValidatePeerCertificateChainResp_ValidationResult int32
+
+const (
+	ValidatePeerCertificateChainResp_UNSPECIFIED ValidatePeerCertificateChainResp_ValidationResult = 0
+	ValidatePeerCertificateChainResp_SUCCESS     ValidatePeerCertificateChainResp_ValidationResult = 1
+	ValidatePeerCertificateChainResp_FAILURE     ValidatePeerCertificateChainResp_ValidationResult = 2
+)
+
+// Enum value maps for ValidatePeerCertificateChainResp_ValidationResult.
+var (
+	ValidatePeerCertificateChainResp_ValidationResult_name = map[int32]string{
+		0: "UNSPECIFIED",
+		1: "SUCCESS",
+		2: "FAILURE",
+	}
+	ValidatePeerCertificateChainResp_ValidationResult_value = map[string]int32{
+		"UNSPECIFIED": 0,
+		"SUCCESS":     1,
+		"FAILURE":     2,
+	}
+)
+
+func (x ValidatePeerCertificateChainResp_ValidationResult) Enum() *ValidatePeerCertificateChainResp_ValidationResult {
+	p := new(ValidatePeerCertificateChainResp_ValidationResult)
+	*p = x
+	return p
+}
+
+func (x ValidatePeerCertificateChainResp_ValidationResult) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ValidatePeerCertificateChainResp_ValidationResult) Descriptor() protoreflect.EnumDescriptor {
+	return file_internal_proto_v2_s2a_s2a_proto_enumTypes[5].Descriptor()
+}
+
+func (ValidatePeerCertificateChainResp_ValidationResult) Type() protoreflect.EnumType {
+	return &file_internal_proto_v2_s2a_s2a_proto_enumTypes[5]
+}
+
+func (x ValidatePeerCertificateChainResp_ValidationResult) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ValidatePeerCertificateChainResp_ValidationResult.Descriptor instead.
+func (ValidatePeerCertificateChainResp_ValidationResult) EnumDescriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{10, 0}
+}
+
+type AlpnPolicy struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// If true, the application MUST perform ALPN negotiation.
+	EnableAlpnNegotiation bool `protobuf:"varint,1,opt,name=enable_alpn_negotiation,json=enableAlpnNegotiation,proto3" json:"enable_alpn_negotiation,omitempty"`
+	// The ordered list of ALPN protocols that specify how the application SHOULD
+	// negotiate ALPN during the TLS handshake.
+	//
+	// The application MAY ignore any ALPN protocols in this list that are not
+	// supported by the application.
+	AlpnProtocols []common_go_proto.AlpnProtocol `protobuf:"varint,2,rep,packed,name=alpn_protocols,json=alpnProtocols,proto3,enum=s2a.proto.v2.AlpnProtocol" json:"alpn_protocols,omitempty"`
+}
+
+func (x *AlpnPolicy) Reset() {
+	*x = AlpnPolicy{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AlpnPolicy) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AlpnPolicy) ProtoMessage() {}
+
+func (x *AlpnPolicy) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AlpnPolicy.ProtoReflect.Descriptor instead.
+func (*AlpnPolicy) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *AlpnPolicy) GetEnableAlpnNegotiation() bool {
+	if x != nil {
+		return x.EnableAlpnNegotiation
+	}
+	return false
+}
+
+func (x *AlpnPolicy) GetAlpnProtocols() []common_go_proto.AlpnProtocol {
+	if x != nil {
+		return x.AlpnProtocols
+	}
+	return nil
+}
+
+type AuthenticationMechanism struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Applications may specify an identity associated to an authentication
+	// mechanism. Otherwise, S2A assumes that the authentication mechanism is
+	// associated with the default identity. If the default identity cannot be
+	// determined, the request is rejected.
+	Identity *common_go_proto1.Identity `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
+	// Types that are assignable to MechanismOneof:
+	//
+	//	*AuthenticationMechanism_Token
+	MechanismOneof isAuthenticationMechanism_MechanismOneof `protobuf_oneof:"mechanism_oneof"`
+}
+
+func (x *AuthenticationMechanism) Reset() {
+	*x = AuthenticationMechanism{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AuthenticationMechanism) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AuthenticationMechanism) ProtoMessage() {}
+
+func (x *AuthenticationMechanism) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AuthenticationMechanism.ProtoReflect.Descriptor instead.
+func (*AuthenticationMechanism) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *AuthenticationMechanism) GetIdentity() *common_go_proto1.Identity {
+	if x != nil {
+		return x.Identity
+	}
+	return nil
+}
+
+func (m *AuthenticationMechanism) GetMechanismOneof() isAuthenticationMechanism_MechanismOneof {
+	if m != nil {
+		return m.MechanismOneof
+	}
+	return nil
+}
+
+func (x *AuthenticationMechanism) GetToken() string {
+	if x, ok := x.GetMechanismOneof().(*AuthenticationMechanism_Token); ok {
+		return x.Token
+	}
+	return ""
+}
+
+type isAuthenticationMechanism_MechanismOneof interface {
+	isAuthenticationMechanism_MechanismOneof()
+}
+
+type AuthenticationMechanism_Token struct {
+	// A token that the application uses to authenticate itself to S2A.
+	Token string `protobuf:"bytes,2,opt,name=token,proto3,oneof"`
+}
+
+func (*AuthenticationMechanism_Token) isAuthenticationMechanism_MechanismOneof() {}
+
+type Status struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The status code that is specific to the application and the implementation
+	// of S2A, e.g., gRPC status code.
+	Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
+	// The status details.
+	Details string `protobuf:"bytes,2,opt,name=details,proto3" json:"details,omitempty"`
+}
+
+func (x *Status) Reset() {
+	*x = Status{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Status) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Status) ProtoMessage() {}
+
+func (x *Status) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Status.ProtoReflect.Descriptor instead.
+func (*Status) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *Status) GetCode() uint32 {
+	if x != nil {
+		return x.Code
+	}
+	return 0
+}
+
+func (x *Status) GetDetails() string {
+	if x != nil {
+		return x.Details
+	}
+	return ""
+}
+
+type GetTlsConfigurationReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The role of the application in the TLS connection.
+	ConnectionSide common_go_proto.ConnectionSide `protobuf:"varint,1,opt,name=connection_side,json=connectionSide,proto3,enum=s2a.proto.v2.ConnectionSide" json:"connection_side,omitempty"`
+	// The server name indication (SNI) extension, which MAY be populated when a
+	// server is offloading to S2A. The SNI is used to determine the server
+	// identity if the local identity in the request is empty.
+	Sni string `protobuf:"bytes,2,opt,name=sni,proto3" json:"sni,omitempty"`
+}
+
+func (x *GetTlsConfigurationReq) Reset() {
+	*x = GetTlsConfigurationReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetTlsConfigurationReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetTlsConfigurationReq) ProtoMessage() {}
+
+func (x *GetTlsConfigurationReq) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetTlsConfigurationReq.ProtoReflect.Descriptor instead.
+func (*GetTlsConfigurationReq) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *GetTlsConfigurationReq) GetConnectionSide() common_go_proto.ConnectionSide {
+	if x != nil {
+		return x.ConnectionSide
+	}
+	return common_go_proto.ConnectionSide(0)
+}
+
+func (x *GetTlsConfigurationReq) GetSni() string {
+	if x != nil {
+		return x.Sni
+	}
+	return ""
+}
+
+type GetTlsConfigurationResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Types that are assignable to TlsConfiguration:
+	//
+	//	*GetTlsConfigurationResp_ClientTlsConfiguration_
+	//	*GetTlsConfigurationResp_ServerTlsConfiguration_
+	TlsConfiguration isGetTlsConfigurationResp_TlsConfiguration `protobuf_oneof:"tls_configuration"`
+}
+
+func (x *GetTlsConfigurationResp) Reset() {
+	*x = GetTlsConfigurationResp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetTlsConfigurationResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetTlsConfigurationResp) ProtoMessage() {}
+
+func (x *GetTlsConfigurationResp) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetTlsConfigurationResp.ProtoReflect.Descriptor instead.
+func (*GetTlsConfigurationResp) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{4}
+}
+
+func (m *GetTlsConfigurationResp) GetTlsConfiguration() isGetTlsConfigurationResp_TlsConfiguration {
+	if m != nil {
+		return m.TlsConfiguration
+	}
+	return nil
+}
+
+func (x *GetTlsConfigurationResp) GetClientTlsConfiguration() *GetTlsConfigurationResp_ClientTlsConfiguration {
+	if x, ok := x.GetTlsConfiguration().(*GetTlsConfigurationResp_ClientTlsConfiguration_); ok {
+		return x.ClientTlsConfiguration
+	}
+	return nil
+}
+
+func (x *GetTlsConfigurationResp) GetServerTlsConfiguration() *GetTlsConfigurationResp_ServerTlsConfiguration {
+	if x, ok := x.GetTlsConfiguration().(*GetTlsConfigurationResp_ServerTlsConfiguration_); ok {
+		return x.ServerTlsConfiguration
+	}
+	return nil
+}
+
+type isGetTlsConfigurationResp_TlsConfiguration interface {
+	isGetTlsConfigurationResp_TlsConfiguration()
+}
+
+type GetTlsConfigurationResp_ClientTlsConfiguration_ struct {
+	ClientTlsConfiguration *GetTlsConfigurationResp_ClientTlsConfiguration `protobuf:"bytes,1,opt,name=client_tls_configuration,json=clientTlsConfiguration,proto3,oneof"`
+}
+
+type GetTlsConfigurationResp_ServerTlsConfiguration_ struct {
+	ServerTlsConfiguration *GetTlsConfigurationResp_ServerTlsConfiguration `protobuf:"bytes,2,opt,name=server_tls_configuration,json=serverTlsConfiguration,proto3,oneof"`
+}
+
+func (*GetTlsConfigurationResp_ClientTlsConfiguration_) isGetTlsConfigurationResp_TlsConfiguration() {
+}
+
+func (*GetTlsConfigurationResp_ServerTlsConfiguration_) isGetTlsConfigurationResp_TlsConfiguration() {
+}
+
+type OffloadPrivateKeyOperationReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The operation the private key is used for.
+	Operation OffloadPrivateKeyOperationReq_PrivateKeyOperation `protobuf:"varint,1,opt,name=operation,proto3,enum=s2a.proto.v2.OffloadPrivateKeyOperationReq_PrivateKeyOperation" json:"operation,omitempty"`
+	// The signature algorithm to be used for signing operations.
+	SignatureAlgorithm SignatureAlgorithm `protobuf:"varint,2,opt,name=signature_algorithm,json=signatureAlgorithm,proto3,enum=s2a.proto.v2.SignatureAlgorithm" json:"signature_algorithm,omitempty"`
+	// The input bytes to be signed or decrypted.
+	//
+	// Types that are assignable to InBytes:
+	//
+	//	*OffloadPrivateKeyOperationReq_RawBytes
+	//	*OffloadPrivateKeyOperationReq_Sha256Digest
+	//	*OffloadPrivateKeyOperationReq_Sha384Digest
+	//	*OffloadPrivateKeyOperationReq_Sha512Digest
+	InBytes isOffloadPrivateKeyOperationReq_InBytes `protobuf_oneof:"in_bytes"`
+}
+
+func (x *OffloadPrivateKeyOperationReq) Reset() {
+	*x = OffloadPrivateKeyOperationReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *OffloadPrivateKeyOperationReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OffloadPrivateKeyOperationReq) ProtoMessage() {}
+
+func (x *OffloadPrivateKeyOperationReq) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use OffloadPrivateKeyOperationReq.ProtoReflect.Descriptor instead.
+func (*OffloadPrivateKeyOperationReq) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *OffloadPrivateKeyOperationReq) GetOperation() OffloadPrivateKeyOperationReq_PrivateKeyOperation {
+	if x != nil {
+		return x.Operation
+	}
+	return OffloadPrivateKeyOperationReq_UNSPECIFIED
+}
+
+func (x *OffloadPrivateKeyOperationReq) GetSignatureAlgorithm() SignatureAlgorithm {
+	if x != nil {
+		return x.SignatureAlgorithm
+	}
+	return SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED
+}
+
+func (m *OffloadPrivateKeyOperationReq) GetInBytes() isOffloadPrivateKeyOperationReq_InBytes {
+	if m != nil {
+		return m.InBytes
+	}
+	return nil
+}
+
+func (x *OffloadPrivateKeyOperationReq) GetRawBytes() []byte {
+	if x, ok := x.GetInBytes().(*OffloadPrivateKeyOperationReq_RawBytes); ok {
+		return x.RawBytes
+	}
+	return nil
+}
+
+func (x *OffloadPrivateKeyOperationReq) GetSha256Digest() []byte {
+	if x, ok := x.GetInBytes().(*OffloadPrivateKeyOperationReq_Sha256Digest); ok {
+		return x.Sha256Digest
+	}
+	return nil
+}
+
+func (x *OffloadPrivateKeyOperationReq) GetSha384Digest() []byte {
+	if x, ok := x.GetInBytes().(*OffloadPrivateKeyOperationReq_Sha384Digest); ok {
+		return x.Sha384Digest
+	}
+	return nil
+}
+
+func (x *OffloadPrivateKeyOperationReq) GetSha512Digest() []byte {
+	if x, ok := x.GetInBytes().(*OffloadPrivateKeyOperationReq_Sha512Digest); ok {
+		return x.Sha512Digest
+	}
+	return nil
+}
+
+type isOffloadPrivateKeyOperationReq_InBytes interface {
+	isOffloadPrivateKeyOperationReq_InBytes()
+}
+
+type OffloadPrivateKeyOperationReq_RawBytes struct {
+	// Raw bytes to be hashed and signed, or decrypted.
+	RawBytes []byte `protobuf:"bytes,4,opt,name=raw_bytes,json=rawBytes,proto3,oneof"`
+}
+
+type OffloadPrivateKeyOperationReq_Sha256Digest struct {
+	// A SHA256 hash to be signed. Must be 32 bytes.
+	Sha256Digest []byte `protobuf:"bytes,5,opt,name=sha256_digest,json=sha256Digest,proto3,oneof"`
+}
+
+type OffloadPrivateKeyOperationReq_Sha384Digest struct {
+	// A SHA384 hash to be signed. Must be 48 bytes.
+	Sha384Digest []byte `protobuf:"bytes,6,opt,name=sha384_digest,json=sha384Digest,proto3,oneof"`
+}
+
+type OffloadPrivateKeyOperationReq_Sha512Digest struct {
+	// A SHA512 hash to be signed. Must be 64 bytes.
+	Sha512Digest []byte `protobuf:"bytes,7,opt,name=sha512_digest,json=sha512Digest,proto3,oneof"`
+}
+
+func (*OffloadPrivateKeyOperationReq_RawBytes) isOffloadPrivateKeyOperationReq_InBytes() {}
+
+func (*OffloadPrivateKeyOperationReq_Sha256Digest) isOffloadPrivateKeyOperationReq_InBytes() {}
+
+func (*OffloadPrivateKeyOperationReq_Sha384Digest) isOffloadPrivateKeyOperationReq_InBytes() {}
+
+func (*OffloadPrivateKeyOperationReq_Sha512Digest) isOffloadPrivateKeyOperationReq_InBytes() {}
+
+type OffloadPrivateKeyOperationResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The signed or decrypted output bytes.
+	OutBytes []byte `protobuf:"bytes,1,opt,name=out_bytes,json=outBytes,proto3" json:"out_bytes,omitempty"`
+}
+
+func (x *OffloadPrivateKeyOperationResp) Reset() {
+	*x = OffloadPrivateKeyOperationResp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *OffloadPrivateKeyOperationResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OffloadPrivateKeyOperationResp) ProtoMessage() {}
+
+func (x *OffloadPrivateKeyOperationResp) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use OffloadPrivateKeyOperationResp.ProtoReflect.Descriptor instead.
+func (*OffloadPrivateKeyOperationResp) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *OffloadPrivateKeyOperationResp) GetOutBytes() []byte {
+	if x != nil {
+		return x.OutBytes
+	}
+	return nil
+}
+
+type OffloadResumptionKeyOperationReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The operation the resumption key is used for.
+	Operation OffloadResumptionKeyOperationReq_ResumptionKeyOperation `protobuf:"varint,1,opt,name=operation,proto3,enum=s2a.proto.v2.OffloadResumptionKeyOperationReq_ResumptionKeyOperation" json:"operation,omitempty"`
+	// The bytes to be encrypted or decrypted.
+	InBytes []byte `protobuf:"bytes,2,opt,name=in_bytes,json=inBytes,proto3" json:"in_bytes,omitempty"`
+}
+
+func (x *OffloadResumptionKeyOperationReq) Reset() {
+	*x = OffloadResumptionKeyOperationReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *OffloadResumptionKeyOperationReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OffloadResumptionKeyOperationReq) ProtoMessage() {}
+
+func (x *OffloadResumptionKeyOperationReq) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use OffloadResumptionKeyOperationReq.ProtoReflect.Descriptor instead.
+func (*OffloadResumptionKeyOperationReq) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *OffloadResumptionKeyOperationReq) GetOperation() OffloadResumptionKeyOperationReq_ResumptionKeyOperation {
+	if x != nil {
+		return x.Operation
+	}
+	return OffloadResumptionKeyOperationReq_UNSPECIFIED
+}
+
+func (x *OffloadResumptionKeyOperationReq) GetInBytes() []byte {
+	if x != nil {
+		return x.InBytes
+	}
+	return nil
+}
+
+type OffloadResumptionKeyOperationResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The encrypted or decrypted bytes.
+	OutBytes []byte `protobuf:"bytes,1,opt,name=out_bytes,json=outBytes,proto3" json:"out_bytes,omitempty"`
+}
+
+func (x *OffloadResumptionKeyOperationResp) Reset() {
+	*x = OffloadResumptionKeyOperationResp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *OffloadResumptionKeyOperationResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OffloadResumptionKeyOperationResp) ProtoMessage() {}
+
+func (x *OffloadResumptionKeyOperationResp) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use OffloadResumptionKeyOperationResp.ProtoReflect.Descriptor instead.
+func (*OffloadResumptionKeyOperationResp) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *OffloadResumptionKeyOperationResp) GetOutBytes() []byte {
+	if x != nil {
+		return x.OutBytes
+	}
+	return nil
+}
+
+type ValidatePeerCertificateChainReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The verification mode that S2A MUST use to validate the peer certificate
+	// chain.
+	Mode ValidatePeerCertificateChainReq_VerificationMode `protobuf:"varint,1,opt,name=mode,proto3,enum=s2a.proto.v2.ValidatePeerCertificateChainReq_VerificationMode" json:"mode,omitempty"`
+	// Types that are assignable to PeerOneof:
+	//
+	//	*ValidatePeerCertificateChainReq_ClientPeer_
+	//	*ValidatePeerCertificateChainReq_ServerPeer_
+	PeerOneof isValidatePeerCertificateChainReq_PeerOneof `protobuf_oneof:"peer_oneof"`
+}
+
+func (x *ValidatePeerCertificateChainReq) Reset() {
+	*x = ValidatePeerCertificateChainReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[9]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ValidatePeerCertificateChainReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ValidatePeerCertificateChainReq) ProtoMessage() {}
+
+func (x *ValidatePeerCertificateChainReq) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[9]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ValidatePeerCertificateChainReq.ProtoReflect.Descriptor instead.
+func (*ValidatePeerCertificateChainReq) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *ValidatePeerCertificateChainReq) GetMode() ValidatePeerCertificateChainReq_VerificationMode {
+	if x != nil {
+		return x.Mode
+	}
+	return ValidatePeerCertificateChainReq_UNSPECIFIED
+}
+
+func (m *ValidatePeerCertificateChainReq) GetPeerOneof() isValidatePeerCertificateChainReq_PeerOneof {
+	if m != nil {
+		return m.PeerOneof
+	}
+	return nil
+}
+
+func (x *ValidatePeerCertificateChainReq) GetClientPeer() *ValidatePeerCertificateChainReq_ClientPeer {
+	if x, ok := x.GetPeerOneof().(*ValidatePeerCertificateChainReq_ClientPeer_); ok {
+		return x.ClientPeer
+	}
+	return nil
+}
+
+func (x *ValidatePeerCertificateChainReq) GetServerPeer() *ValidatePeerCertificateChainReq_ServerPeer {
+	if x, ok := x.GetPeerOneof().(*ValidatePeerCertificateChainReq_ServerPeer_); ok {
+		return x.ServerPeer
+	}
+	return nil
+}
+
+type isValidatePeerCertificateChainReq_PeerOneof interface {
+	isValidatePeerCertificateChainReq_PeerOneof()
+}
+
+type ValidatePeerCertificateChainReq_ClientPeer_ struct {
+	ClientPeer *ValidatePeerCertificateChainReq_ClientPeer `protobuf:"bytes,2,opt,name=client_peer,json=clientPeer,proto3,oneof"`
+}
+
+type ValidatePeerCertificateChainReq_ServerPeer_ struct {
+	ServerPeer *ValidatePeerCertificateChainReq_ServerPeer `protobuf:"bytes,3,opt,name=server_peer,json=serverPeer,proto3,oneof"`
+}
+
+func (*ValidatePeerCertificateChainReq_ClientPeer_) isValidatePeerCertificateChainReq_PeerOneof() {}
+
+func (*ValidatePeerCertificateChainReq_ServerPeer_) isValidatePeerCertificateChainReq_PeerOneof() {}
+
+type ValidatePeerCertificateChainResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The result of validating the peer certificate chain.
+	ValidationResult ValidatePeerCertificateChainResp_ValidationResult `protobuf:"varint,1,opt,name=validation_result,json=validationResult,proto3,enum=s2a.proto.v2.ValidatePeerCertificateChainResp_ValidationResult" json:"validation_result,omitempty"`
+	// The validation details. This field is only populated when the validation
+	// result is NOT SUCCESS.
+	ValidationDetails string `protobuf:"bytes,2,opt,name=validation_details,json=validationDetails,proto3" json:"validation_details,omitempty"`
+	// The S2A context contains information from the peer certificate chain.
+	//
+	// The S2A context MAY be populated even if validation of the peer certificate
+	// chain fails.
+	Context *s2a_context_go_proto.S2AContext `protobuf:"bytes,3,opt,name=context,proto3" json:"context,omitempty"`
+}
+
+func (x *ValidatePeerCertificateChainResp) Reset() {
+	*x = ValidatePeerCertificateChainResp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[10]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ValidatePeerCertificateChainResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ValidatePeerCertificateChainResp) ProtoMessage() {}
+
+func (x *ValidatePeerCertificateChainResp) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[10]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ValidatePeerCertificateChainResp.ProtoReflect.Descriptor instead.
+func (*ValidatePeerCertificateChainResp) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *ValidatePeerCertificateChainResp) GetValidationResult() ValidatePeerCertificateChainResp_ValidationResult {
+	if x != nil {
+		return x.ValidationResult
+	}
+	return ValidatePeerCertificateChainResp_UNSPECIFIED
+}
+
+func (x *ValidatePeerCertificateChainResp) GetValidationDetails() string {
+	if x != nil {
+		return x.ValidationDetails
+	}
+	return ""
+}
+
+func (x *ValidatePeerCertificateChainResp) GetContext() *s2a_context_go_proto.S2AContext {
+	if x != nil {
+		return x.Context
+	}
+	return nil
+}
+
+type SessionReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The identity corresponding to the TLS configurations that MUST be used for
+	// the TLS handshake.
+	//
+	// If a managed identity already exists, the local identity and authentication
+	// mechanisms are ignored. If a managed identity doesn't exist and the local
+	// identity is not populated, S2A will try to deduce the managed identity to
+	// use from the SNI extension. If that also fails, S2A uses the default
+	// identity (if one exists).
+	LocalIdentity *common_go_proto1.Identity `protobuf:"bytes,1,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"`
+	// The authentication mechanisms that the application wishes to use to
+	// authenticate to S2A, ordered by preference. S2A will always use the first
+	// authentication mechanism that matches the managed identity.
+	AuthenticationMechanisms []*AuthenticationMechanism `protobuf:"bytes,2,rep,name=authentication_mechanisms,json=authenticationMechanisms,proto3" json:"authentication_mechanisms,omitempty"`
+	// Types that are assignable to ReqOneof:
+	//
+	//	*SessionReq_GetTlsConfigurationReq
+	//	*SessionReq_OffloadPrivateKeyOperationReq
+	//	*SessionReq_OffloadResumptionKeyOperationReq
+	//	*SessionReq_ValidatePeerCertificateChainReq
+	ReqOneof isSessionReq_ReqOneof `protobuf_oneof:"req_oneof"`
+}
+
+func (x *SessionReq) Reset() {
+	*x = SessionReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[11]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SessionReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SessionReq) ProtoMessage() {}
+
+func (x *SessionReq) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[11]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SessionReq.ProtoReflect.Descriptor instead.
+func (*SessionReq) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{11}
+}
+
+func (x *SessionReq) GetLocalIdentity() *common_go_proto1.Identity {
+	if x != nil {
+		return x.LocalIdentity
+	}
+	return nil
+}
+
+func (x *SessionReq) GetAuthenticationMechanisms() []*AuthenticationMechanism {
+	if x != nil {
+		return x.AuthenticationMechanisms
+	}
+	return nil
+}
+
+func (m *SessionReq) GetReqOneof() isSessionReq_ReqOneof {
+	if m != nil {
+		return m.ReqOneof
+	}
+	return nil
+}
+
+func (x *SessionReq) GetGetTlsConfigurationReq() *GetTlsConfigurationReq {
+	if x, ok := x.GetReqOneof().(*SessionReq_GetTlsConfigurationReq); ok {
+		return x.GetTlsConfigurationReq
+	}
+	return nil
+}
+
+func (x *SessionReq) GetOffloadPrivateKeyOperationReq() *OffloadPrivateKeyOperationReq {
+	if x, ok := x.GetReqOneof().(*SessionReq_OffloadPrivateKeyOperationReq); ok {
+		return x.OffloadPrivateKeyOperationReq
+	}
+	return nil
+}
+
+func (x *SessionReq) GetOffloadResumptionKeyOperationReq() *OffloadResumptionKeyOperationReq {
+	if x, ok := x.GetReqOneof().(*SessionReq_OffloadResumptionKeyOperationReq); ok {
+		return x.OffloadResumptionKeyOperationReq
+	}
+	return nil
+}
+
+func (x *SessionReq) GetValidatePeerCertificateChainReq() *ValidatePeerCertificateChainReq {
+	if x, ok := x.GetReqOneof().(*SessionReq_ValidatePeerCertificateChainReq); ok {
+		return x.ValidatePeerCertificateChainReq
+	}
+	return nil
+}
+
+type isSessionReq_ReqOneof interface {
+	isSessionReq_ReqOneof()
+}
+
+type SessionReq_GetTlsConfigurationReq struct {
+	// Requests the certificate chain and TLS configuration corresponding to the
+	// local identity, which the application MUST use to negotiate the TLS
+	// handshake.
+	GetTlsConfigurationReq *GetTlsConfigurationReq `protobuf:"bytes,3,opt,name=get_tls_configuration_req,json=getTlsConfigurationReq,proto3,oneof"`
+}
+
+type SessionReq_OffloadPrivateKeyOperationReq struct {
+	// Signs or decrypts the input bytes using a private key corresponding to
+	// the local identity in the request.
+	//
+	// WARNING: More than one OffloadPrivateKeyOperationReq may be sent to the
+	// S2Av2 by a server during a TLS 1.2 handshake.
+	OffloadPrivateKeyOperationReq *OffloadPrivateKeyOperationReq `protobuf:"bytes,4,opt,name=offload_private_key_operation_req,json=offloadPrivateKeyOperationReq,proto3,oneof"`
+}
+
+type SessionReq_OffloadResumptionKeyOperationReq struct {
+	// Encrypts or decrypts the input bytes using a resumption key corresponding
+	// to the local identity in the request.
+	OffloadResumptionKeyOperationReq *OffloadResumptionKeyOperationReq `protobuf:"bytes,5,opt,name=offload_resumption_key_operation_req,json=offloadResumptionKeyOperationReq,proto3,oneof"`
+}
+
+type SessionReq_ValidatePeerCertificateChainReq struct {
+	// Verifies the peer's certificate chain using
+	// (a) trust bundles corresponding to the local identity in the request, and
+	// (b) the verification mode in the request.
+	ValidatePeerCertificateChainReq *ValidatePeerCertificateChainReq `protobuf:"bytes,6,opt,name=validate_peer_certificate_chain_req,json=validatePeerCertificateChainReq,proto3,oneof"`
+}
+
+func (*SessionReq_GetTlsConfigurationReq) isSessionReq_ReqOneof() {}
+
+func (*SessionReq_OffloadPrivateKeyOperationReq) isSessionReq_ReqOneof() {}
+
+func (*SessionReq_OffloadResumptionKeyOperationReq) isSessionReq_ReqOneof() {}
+
+func (*SessionReq_ValidatePeerCertificateChainReq) isSessionReq_ReqOneof() {}
+
+type SessionResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Status of the session response.
+	//
+	// The status field is populated so that if an error occurs when making an
+	// individual request, then communication with the S2A may continue. If an
+	// error is returned directly (e.g. at the gRPC layer), then it may result
+	// that the bidirectional stream being closed.
+	Status *Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
+	// Types that are assignable to RespOneof:
+	//
+	//	*SessionResp_GetTlsConfigurationResp
+	//	*SessionResp_OffloadPrivateKeyOperationResp
+	//	*SessionResp_OffloadResumptionKeyOperationResp
+	//	*SessionResp_ValidatePeerCertificateChainResp
+	RespOneof isSessionResp_RespOneof `protobuf_oneof:"resp_oneof"`
+}
+
+func (x *SessionResp) Reset() {
+	*x = SessionResp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[12]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SessionResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SessionResp) ProtoMessage() {}
+
+func (x *SessionResp) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[12]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SessionResp.ProtoReflect.Descriptor instead.
+func (*SessionResp) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *SessionResp) GetStatus() *Status {
+	if x != nil {
+		return x.Status
+	}
+	return nil
+}
+
+func (m *SessionResp) GetRespOneof() isSessionResp_RespOneof {
+	if m != nil {
+		return m.RespOneof
+	}
+	return nil
+}
+
+func (x *SessionResp) GetGetTlsConfigurationResp() *GetTlsConfigurationResp {
+	if x, ok := x.GetRespOneof().(*SessionResp_GetTlsConfigurationResp); ok {
+		return x.GetTlsConfigurationResp
+	}
+	return nil
+}
+
+func (x *SessionResp) GetOffloadPrivateKeyOperationResp() *OffloadPrivateKeyOperationResp {
+	if x, ok := x.GetRespOneof().(*SessionResp_OffloadPrivateKeyOperationResp); ok {
+		return x.OffloadPrivateKeyOperationResp
+	}
+	return nil
+}
+
+func (x *SessionResp) GetOffloadResumptionKeyOperationResp() *OffloadResumptionKeyOperationResp {
+	if x, ok := x.GetRespOneof().(*SessionResp_OffloadResumptionKeyOperationResp); ok {
+		return x.OffloadResumptionKeyOperationResp
+	}
+	return nil
+}
+
+func (x *SessionResp) GetValidatePeerCertificateChainResp() *ValidatePeerCertificateChainResp {
+	if x, ok := x.GetRespOneof().(*SessionResp_ValidatePeerCertificateChainResp); ok {
+		return x.ValidatePeerCertificateChainResp
+	}
+	return nil
+}
+
+type isSessionResp_RespOneof interface {
+	isSessionResp_RespOneof()
+}
+
+type SessionResp_GetTlsConfigurationResp struct {
+	// Contains the certificate chain and TLS configurations corresponding to
+	// the local identity.
+	GetTlsConfigurationResp *GetTlsConfigurationResp `protobuf:"bytes,2,opt,name=get_tls_configuration_resp,json=getTlsConfigurationResp,proto3,oneof"`
+}
+
+type SessionResp_OffloadPrivateKeyOperationResp struct {
+	// Contains the signed or encrypted output bytes using the private key
+	// corresponding to the local identity.
+	OffloadPrivateKeyOperationResp *OffloadPrivateKeyOperationResp `protobuf:"bytes,3,opt,name=offload_private_key_operation_resp,json=offloadPrivateKeyOperationResp,proto3,oneof"`
+}
+
+type SessionResp_OffloadResumptionKeyOperationResp struct {
+	// Contains the encrypted or decrypted output bytes using the resumption key
+	// corresponding to the local identity.
+	OffloadResumptionKeyOperationResp *OffloadResumptionKeyOperationResp `protobuf:"bytes,4,opt,name=offload_resumption_key_operation_resp,json=offloadResumptionKeyOperationResp,proto3,oneof"`
+}
+
+type SessionResp_ValidatePeerCertificateChainResp struct {
+	// Contains the validation result, peer identity and fingerprints of peer
+	// certificates.
+	ValidatePeerCertificateChainResp *ValidatePeerCertificateChainResp `protobuf:"bytes,5,opt,name=validate_peer_certificate_chain_resp,json=validatePeerCertificateChainResp,proto3,oneof"`
+}
+
+func (*SessionResp_GetTlsConfigurationResp) isSessionResp_RespOneof() {}
+
+func (*SessionResp_OffloadPrivateKeyOperationResp) isSessionResp_RespOneof() {}
+
+func (*SessionResp_OffloadResumptionKeyOperationResp) isSessionResp_RespOneof() {}
+
+func (*SessionResp_ValidatePeerCertificateChainResp) isSessionResp_RespOneof() {}
+
+// Next ID: 8
+type GetTlsConfigurationResp_ClientTlsConfiguration struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The certificate chain that the client MUST use for the TLS handshake.
+	// It's a list of PEM-encoded certificates, ordered from leaf to root,
+	// excluding the root.
+	CertificateChain []string `protobuf:"bytes,1,rep,name=certificate_chain,json=certificateChain,proto3" json:"certificate_chain,omitempty"`
+	// The minimum TLS version number that the client MUST use for the TLS
+	// handshake. If this field is not provided, the client MUST use the default
+	// minimum version of the client's TLS library.
+	MinTlsVersion common_go_proto.TLSVersion `protobuf:"varint,2,opt,name=min_tls_version,json=minTlsVersion,proto3,enum=s2a.proto.v2.TLSVersion" json:"min_tls_version,omitempty"`
+	// The maximum TLS version number that the client MUST use for the TLS
+	// handshake. If this field is not provided, the client MUST use the default
+	// maximum version of the client's TLS library.
+	MaxTlsVersion common_go_proto.TLSVersion `protobuf:"varint,3,opt,name=max_tls_version,json=maxTlsVersion,proto3,enum=s2a.proto.v2.TLSVersion" json:"max_tls_version,omitempty"`
+	// The ordered list of TLS 1.0-1.2 ciphersuites that the client MAY offer to
+	// negotiate in the TLS handshake.
+	Ciphersuites []common_go_proto.Ciphersuite `protobuf:"varint,6,rep,packed,name=ciphersuites,proto3,enum=s2a.proto.v2.Ciphersuite" json:"ciphersuites,omitempty"`
+	// The policy that dictates how the client negotiates ALPN during the TLS
+	// handshake.
+	AlpnPolicy *AlpnPolicy `protobuf:"bytes,7,opt,name=alpn_policy,json=alpnPolicy,proto3" json:"alpn_policy,omitempty"`
+}
+
+func (x *GetTlsConfigurationResp_ClientTlsConfiguration) Reset() {
+	*x = GetTlsConfigurationResp_ClientTlsConfiguration{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[13]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetTlsConfigurationResp_ClientTlsConfiguration) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetTlsConfigurationResp_ClientTlsConfiguration) ProtoMessage() {}
+
+func (x *GetTlsConfigurationResp_ClientTlsConfiguration) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[13]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetTlsConfigurationResp_ClientTlsConfiguration.ProtoReflect.Descriptor instead.
+func (*GetTlsConfigurationResp_ClientTlsConfiguration) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{4, 0}
+}
+
+func (x *GetTlsConfigurationResp_ClientTlsConfiguration) GetCertificateChain() []string {
+	if x != nil {
+		return x.CertificateChain
+	}
+	return nil
+}
+
+func (x *GetTlsConfigurationResp_ClientTlsConfiguration) GetMinTlsVersion() common_go_proto.TLSVersion {
+	if x != nil {
+		return x.MinTlsVersion
+	}
+	return common_go_proto.TLSVersion(0)
+}
+
+func (x *GetTlsConfigurationResp_ClientTlsConfiguration) GetMaxTlsVersion() common_go_proto.TLSVersion {
+	if x != nil {
+		return x.MaxTlsVersion
+	}
+	return common_go_proto.TLSVersion(0)
+}
+
+func (x *GetTlsConfigurationResp_ClientTlsConfiguration) GetCiphersuites() []common_go_proto.Ciphersuite {
+	if x != nil {
+		return x.Ciphersuites
+	}
+	return nil
+}
+
+func (x *GetTlsConfigurationResp_ClientTlsConfiguration) GetAlpnPolicy() *AlpnPolicy {
+	if x != nil {
+		return x.AlpnPolicy
+	}
+	return nil
+}
+
+// Next ID: 12
+type GetTlsConfigurationResp_ServerTlsConfiguration struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The certificate chain that the server MUST use for the TLS handshake.
+	// It's a list of PEM-encoded certificates, ordered from leaf to root,
+	// excluding the root.
+	CertificateChain []string `protobuf:"bytes,1,rep,name=certificate_chain,json=certificateChain,proto3" json:"certificate_chain,omitempty"`
+	// The minimum TLS version number that the server MUST use for the TLS
+	// handshake. If this field is not provided, the server MUST use the default
+	// minimum version of the server's TLS library.
+	MinTlsVersion common_go_proto.TLSVersion `protobuf:"varint,2,opt,name=min_tls_version,json=minTlsVersion,proto3,enum=s2a.proto.v2.TLSVersion" json:"min_tls_version,omitempty"`
+	// The maximum TLS version number that the server MUST use for the TLS
+	// handshake. If this field is not provided, the server MUST use the default
+	// maximum version of the server's TLS library.
+	MaxTlsVersion common_go_proto.TLSVersion `protobuf:"varint,3,opt,name=max_tls_version,json=maxTlsVersion,proto3,enum=s2a.proto.v2.TLSVersion" json:"max_tls_version,omitempty"`
+	// The ordered list of TLS 1.0-1.2 ciphersuites that the server MAY offer to
+	// negotiate in the TLS handshake.
+	Ciphersuites []common_go_proto.Ciphersuite `protobuf:"varint,10,rep,packed,name=ciphersuites,proto3,enum=s2a.proto.v2.Ciphersuite" json:"ciphersuites,omitempty"`
+	// Whether to enable TLS resumption.
+	TlsResumptionEnabled bool `protobuf:"varint,6,opt,name=tls_resumption_enabled,json=tlsResumptionEnabled,proto3" json:"tls_resumption_enabled,omitempty"`
+	// Whether the server MUST request a client certificate (i.e. to negotiate
+	// TLS vs. mTLS).
+	RequestClientCertificate GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate `protobuf:"varint,7,opt,name=request_client_certificate,json=requestClientCertificate,proto3,enum=s2a.proto.v2.GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate" json:"request_client_certificate,omitempty"`
+	// Returns the maximum number of extra bytes that
+	// |OffloadResumptionKeyOperation| can add to the number of unencrypted
+	// bytes to form the encrypted bytes.
+	MaxOverheadOfTicketAead uint32 `protobuf:"varint,9,opt,name=max_overhead_of_ticket_aead,json=maxOverheadOfTicketAead,proto3" json:"max_overhead_of_ticket_aead,omitempty"`
+	// The policy that dictates how the server negotiates ALPN during the TLS
+	// handshake.
+	AlpnPolicy *AlpnPolicy `protobuf:"bytes,11,opt,name=alpn_policy,json=alpnPolicy,proto3" json:"alpn_policy,omitempty"`
+}
+
+func (x *GetTlsConfigurationResp_ServerTlsConfiguration) Reset() {
+	*x = GetTlsConfigurationResp_ServerTlsConfiguration{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[14]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetTlsConfigurationResp_ServerTlsConfiguration) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetTlsConfigurationResp_ServerTlsConfiguration) ProtoMessage() {}
+
+func (x *GetTlsConfigurationResp_ServerTlsConfiguration) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[14]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetTlsConfigurationResp_ServerTlsConfiguration.ProtoReflect.Descriptor instead.
+func (*GetTlsConfigurationResp_ServerTlsConfiguration) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{4, 1}
+}
+
+func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetCertificateChain() []string {
+	if x != nil {
+		return x.CertificateChain
+	}
+	return nil
+}
+
+func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetMinTlsVersion() common_go_proto.TLSVersion {
+	if x != nil {
+		return x.MinTlsVersion
+	}
+	return common_go_proto.TLSVersion(0)
+}
+
+func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetMaxTlsVersion() common_go_proto.TLSVersion {
+	if x != nil {
+		return x.MaxTlsVersion
+	}
+	return common_go_proto.TLSVersion(0)
+}
+
+func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetCiphersuites() []common_go_proto.Ciphersuite {
+	if x != nil {
+		return x.Ciphersuites
+	}
+	return nil
+}
+
+func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetTlsResumptionEnabled() bool {
+	if x != nil {
+		return x.TlsResumptionEnabled
+	}
+	return false
+}
+
+func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetRequestClientCertificate() GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate {
+	if x != nil {
+		return x.RequestClientCertificate
+	}
+	return GetTlsConfigurationResp_ServerTlsConfiguration_UNSPECIFIED
+}
+
+func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetMaxOverheadOfTicketAead() uint32 {
+	if x != nil {
+		return x.MaxOverheadOfTicketAead
+	}
+	return 0
+}
+
+func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetAlpnPolicy() *AlpnPolicy {
+	if x != nil {
+		return x.AlpnPolicy
+	}
+	return nil
+}
+
+type ValidatePeerCertificateChainReq_ClientPeer struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The certificate chain to be verified. The chain MUST be a list of
+	// DER-encoded certificates, ordered from leaf to root, excluding the root.
+	CertificateChain [][]byte `protobuf:"bytes,1,rep,name=certificate_chain,json=certificateChain,proto3" json:"certificate_chain,omitempty"`
+}
+
+func (x *ValidatePeerCertificateChainReq_ClientPeer) Reset() {
+	*x = ValidatePeerCertificateChainReq_ClientPeer{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[15]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ValidatePeerCertificateChainReq_ClientPeer) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ValidatePeerCertificateChainReq_ClientPeer) ProtoMessage() {}
+
+func (x *ValidatePeerCertificateChainReq_ClientPeer) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[15]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ValidatePeerCertificateChainReq_ClientPeer.ProtoReflect.Descriptor instead.
+func (*ValidatePeerCertificateChainReq_ClientPeer) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{9, 0}
+}
+
+func (x *ValidatePeerCertificateChainReq_ClientPeer) GetCertificateChain() [][]byte {
+	if x != nil {
+		return x.CertificateChain
+	}
+	return nil
+}
+
+type ValidatePeerCertificateChainReq_ServerPeer struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The certificate chain to be verified. The chain MUST be a list of
+	// DER-encoded certificates, ordered from leaf to root, excluding the root.
+	CertificateChain [][]byte `protobuf:"bytes,1,rep,name=certificate_chain,json=certificateChain,proto3" json:"certificate_chain,omitempty"`
+	// The expected hostname of the server.
+	ServerHostname string `protobuf:"bytes,2,opt,name=server_hostname,json=serverHostname,proto3" json:"server_hostname,omitempty"`
+	// The UnrestrictedClientPolicy specified by the user.
+	SerializedUnrestrictedClientPolicy []byte `protobuf:"bytes,3,opt,name=serialized_unrestricted_client_policy,json=serializedUnrestrictedClientPolicy,proto3" json:"serialized_unrestricted_client_policy,omitempty"`
+}
+
+func (x *ValidatePeerCertificateChainReq_ServerPeer) Reset() {
+	*x = ValidatePeerCertificateChainReq_ServerPeer{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[16]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ValidatePeerCertificateChainReq_ServerPeer) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ValidatePeerCertificateChainReq_ServerPeer) ProtoMessage() {}
+
+func (x *ValidatePeerCertificateChainReq_ServerPeer) ProtoReflect() protoreflect.Message {
+	mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[16]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ValidatePeerCertificateChainReq_ServerPeer.ProtoReflect.Descriptor instead.
+func (*ValidatePeerCertificateChainReq_ServerPeer) Descriptor() ([]byte, []int) {
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{9, 1}
+}
+
+func (x *ValidatePeerCertificateChainReq_ServerPeer) GetCertificateChain() [][]byte {
+	if x != nil {
+		return x.CertificateChain
+	}
+	return nil
+}
+
+func (x *ValidatePeerCertificateChainReq_ServerPeer) GetServerHostname() string {
+	if x != nil {
+		return x.ServerHostname
+	}
+	return ""
+}
+
+func (x *ValidatePeerCertificateChainReq_ServerPeer) GetSerializedUnrestrictedClientPolicy() []byte {
+	if x != nil {
+		return x.SerializedUnrestrictedClientPolicy
+	}
+	return nil
+}
+
+var File_internal_proto_v2_s2a_s2a_proto protoreflect.FileDescriptor
+
+var file_internal_proto_v2_s2a_s2a_proto_rawDesc = []byte{
+	0x0a, 0x1f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2f, 0x76, 0x32, 0x2f, 0x73, 0x32, 0x61, 0x2f, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x12, 0x0c, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x1a,
+	0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f,
+	0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x1a, 0x25, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f,
+	0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2f, 0x69, 0x6e, 0x74, 0x65,
+	0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x32,
+	0x61, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x73, 0x32, 0x61, 0x5f, 0x63, 0x6f,
+	0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x87, 0x01, 0x0a, 0x0a,
+	0x41, 0x6c, 0x70, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x36, 0x0a, 0x17, 0x65, 0x6e,
+	0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x6c, 0x70, 0x6e, 0x5f, 0x6e, 0x65, 0x67, 0x6f, 0x74, 0x69,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x65, 0x6e, 0x61,
+	0x62, 0x6c, 0x65, 0x41, 0x6c, 0x70, 0x6e, 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0e, 0x61, 0x6c, 0x70, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x63, 0x6f, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x73, 0x32, 0x61,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6c, 0x70, 0x6e, 0x50, 0x72,
+	0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x0d, 0x61, 0x6c, 0x70, 0x6e, 0x50, 0x72, 0x6f, 0x74,
+	0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x22, 0x75, 0x0a, 0x17, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74,
+	0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d,
+	0x12, 0x2f, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49,
+	0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
+	0x79, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x48, 0x00, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x11, 0x0a, 0x0f, 0x6d, 0x65, 0x63,
+	0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x36, 0x0a, 0x06,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65,
+	0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74,
+	0x61, 0x69, 0x6c, 0x73, 0x22, 0x71, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x45,
+	0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x69, 0x64,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
+	0x6e, 0x53, 0x69, 0x64, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
+	0x6e, 0x53, 0x69, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x6e, 0x69, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x03, 0x73, 0x6e, 0x69, 0x22, 0xf1, 0x0b, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x54,
+	0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x70, 0x12, 0x78, 0x0a, 0x18, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6c,
+	0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x2e, 0x43, 0x6c, 0x69,
+	0x65, 0x6e, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x16, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x6c, 0x73,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x78, 0x0a,
+	0x18, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x3c, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x47,
+	0x65, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6c, 0x73,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52,
+	0x16, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xcf, 0x02, 0x0a, 0x16, 0x43, 0x6c, 0x69, 0x65,
+	0x6e, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+	0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x63,
+	0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12,
+	0x40, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69,
+	0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69,
+	0x6f, 0x6e, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x54, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+	0x6e, 0x12, 0x40, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65, 0x72,
+	0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x73, 0x32, 0x61,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72,
+	0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x54, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73,
+	0x69, 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69,
+	0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x73, 0x32, 0x61, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73,
+	0x75, 0x69, 0x74, 0x65, 0x52, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, 0x74,
+	0x65, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x61, 0x6c, 0x70, 0x6e, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63,
+	0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6c, 0x70, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63,
+	0x79, 0x52, 0x0a, 0x61, 0x6c, 0x70, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4a, 0x04, 0x08,
+	0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x1a, 0xfa, 0x06, 0x0a, 0x16, 0x53, 0x65,
+	0x72, 0x76, 0x65, 0x72, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+	0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52,
+	0x10, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69,
+	0x6e, 0x12, 0x40, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65, 0x72,
+	0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x73, 0x32, 0x61,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72,
+	0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x54, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73,
+	0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76,
+	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x73,
+	0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x4c, 0x53, 0x56,
+	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x54, 0x6c, 0x73, 0x56, 0x65,
+	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73,
+	0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x73, 0x32,
+	0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65,
+	0x72, 0x73, 0x75, 0x69, 0x74, 0x65, 0x52, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75,
+	0x69, 0x74, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x74, 0x6c, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x75,
+	0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06,
+	0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x74, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74,
+	0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x93, 0x01, 0x0a, 0x1a, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x65,
+	0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32,
+	0x55, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x47,
+	0x65, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6c, 0x73,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69,
+	0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x18, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43,
+	0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+	0x12, 0x3c, 0x0a, 0x1b, 0x6d, 0x61, 0x78, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x61, 0x64,
+	0x5f, 0x6f, 0x66, 0x5f, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x61, 0x65, 0x61, 0x64, 0x18,
+	0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x17, 0x6d, 0x61, 0x78, 0x4f, 0x76, 0x65, 0x72, 0x68, 0x65,
+	0x61, 0x64, 0x4f, 0x66, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x41, 0x65, 0x61, 0x64, 0x12, 0x39,
+	0x0a, 0x0b, 0x61, 0x6c, 0x70, 0x6e, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x0b, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+	0x76, 0x32, 0x2e, 0x41, 0x6c, 0x70, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0a, 0x61,
+	0x6c, 0x70, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x9e, 0x02, 0x0a, 0x18, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69,
+	0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
+	0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x4f, 0x4e, 0x54, 0x5f,
+	0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43,
+	0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x2e, 0x0a, 0x2a,
+	0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43,
+	0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x5f, 0x42, 0x55, 0x54, 0x5f, 0x44,
+	0x4f, 0x4e, 0x54, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x10, 0x02, 0x12, 0x29, 0x0a, 0x25,
+	0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43,
+	0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x56,
+	0x45, 0x52, 0x49, 0x46, 0x59, 0x10, 0x03, 0x12, 0x3a, 0x0a, 0x36, 0x52, 0x45, 0x51, 0x55, 0x45,
+	0x53, 0x54, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x5f, 0x43,
+	0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54,
+	0x45, 0x5f, 0x42, 0x55, 0x54, 0x5f, 0x44, 0x4f, 0x4e, 0x54, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46,
+	0x59, 0x10, 0x04, 0x12, 0x35, 0x0a, 0x31, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x41,
+	0x4e, 0x44, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e,
+	0x54, 0x5f, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x4e,
+	0x44, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05,
+	0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x42, 0x13, 0x0a, 0x11, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb0, 0x03, 0x0a, 0x1d,
+	0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65,
+	0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x5d, 0x0a,
+	0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
+	0x32, 0x3f, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e,
+	0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65,
+	0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x2e, 0x50, 0x72,
+	0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x51, 0x0a, 0x13,
+	0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69,
+	0x74, 0x68, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x73, 0x32, 0x61, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
+	0x72, 0x65, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x52, 0x12, 0x73, 0x69, 0x67,
+	0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12,
+	0x1d, 0x0a, 0x09, 0x72, 0x61, 0x77, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x72, 0x61, 0x77, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x25,
+	0x0a, 0x0d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18,
+	0x05, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x44,
+	0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0d, 0x73, 0x68, 0x61, 0x33, 0x38, 0x34, 0x5f,
+	0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0c,
+	0x73, 0x68, 0x61, 0x33, 0x38, 0x34, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0d,
+	0x73, 0x68, 0x61, 0x35, 0x31, 0x32, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x07, 0x20,
+	0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x35, 0x31, 0x32, 0x44, 0x69, 0x67,
+	0x65, 0x73, 0x74, 0x22, 0x3d, 0x0a, 0x13, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65,
+	0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e,
+	0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53,
+	0x49, 0x47, 0x4e, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50, 0x54,
+	0x10, 0x02, 0x42, 0x0a, 0x0a, 0x08, 0x69, 0x6e, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0x3d,
+	0x0a, 0x1e, 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65,
+	0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
+	0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0c, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xe7, 0x01,
+	0x0a, 0x20, 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74,
+	0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x65, 0x71, 0x12, 0x63, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x45, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75,
+	0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x52, 0x65, 0x71, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70,
+	0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x6e, 0x5f, 0x62, 0x79,
+	0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x69, 0x6e, 0x42, 0x79, 0x74,
+	0x65, 0x73, 0x22, 0x43, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x0a, 0x0b,
+	0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a,
+	0x07, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45,
+	0x43, 0x52, 0x59, 0x50, 0x54, 0x10, 0x02, 0x22, 0x40, 0x0a, 0x21, 0x4f, 0x66, 0x66, 0x6c, 0x6f,
+	0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4f,
+	0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09,
+	0x6f, 0x75, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
+	0x08, 0x6f, 0x75, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xf8, 0x04, 0x0a, 0x1f, 0x56, 0x61,
+	0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+	0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x52, 0x0a,
+	0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3e, 0x2e, 0x73, 0x32,
+	0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64,
+	0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+	0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66,
+	0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64,
+	0x65, 0x12, 0x5b, 0x0a, 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x65, 0x65, 0x72,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65,
+	0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61,
+	0x69, 0x6e, 0x52, 0x65, 0x71, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x65, 0x65, 0x72,
+	0x48, 0x00, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, 0x5b,
+	0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+	0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x43,
+	0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52,
+	0x65, 0x71, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x65, 0x65, 0x72, 0x48, 0x00, 0x52,
+	0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x65, 0x65, 0x72, 0x1a, 0x39, 0x0a, 0x0a, 0x43,
+	0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x65, 0x72,
+	0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01,
+	0x20, 0x03, 0x28, 0x0c, 0x52, 0x10, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+	0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x1a, 0xb5, 0x01, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65,
+	0x72, 0x50, 0x65, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+	0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c,
+	0x52, 0x10, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61,
+	0x69, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x68, 0x6f, 0x73,
+	0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x72,
+	0x76, 0x65, 0x72, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x51, 0x0a, 0x25, 0x73,
+	0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x75, 0x6e, 0x72, 0x65, 0x73, 0x74,
+	0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x6f,
+	0x6c, 0x69, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x22, 0x73, 0x65, 0x72, 0x69,
+	0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x55, 0x6e, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74,
+	0x65, 0x64, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x46,
+	0x0a, 0x10, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f,
+	0x64, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
+	0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, 0x10, 0x01, 0x12,
+	0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x4f, 0x5f, 0x47, 0x4f,
+	0x4f, 0x47, 0x4c, 0x45, 0x10, 0x02, 0x42, 0x0c, 0x0a, 0x0a, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x6f,
+	0x6e, 0x65, 0x6f, 0x66, 0x22, 0xb2, 0x02, 0x0a, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
+	0x65, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+	0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x6c, 0x0a, 0x11, 0x76, 0x61, 0x6c,
+	0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0e, 0x32, 0x3f, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2e, 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72,
+	0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e,
+	0x52, 0x65, 0x73, 0x70, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2d, 0x0a, 0x12, 0x76, 0x61, 0x6c, 0x69, 0x64,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44,
+	0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x32, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78,
+	0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x32, 0x41, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78,
+	0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3d, 0x0a, 0x10, 0x56, 0x61,
+	0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x0f,
+	0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
+	0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07,
+	0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x02, 0x22, 0x97, 0x05, 0x0a, 0x0a, 0x53, 0x65,
+	0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x3a, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61,
+	0x6c, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65,
+	0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e,
+	0x74, 0x69, 0x74, 0x79, 0x12, 0x62, 0x0a, 0x19, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69,
+	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d,
+	0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x52, 0x18,
+	0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65,
+	0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x73, 0x12, 0x61, 0x0a, 0x19, 0x67, 0x65, 0x74, 0x5f,
+	0x74, 0x6c, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x32,
+	0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6c,
+	0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
+	0x71, 0x48, 0x00, 0x52, 0x16, 0x67, 0x65, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x77, 0x0a, 0x21, 0x6f,
+	0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b,
+	0x65, 0x79, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x69,
+	0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x1d, 0x6f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72,
+	0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x52, 0x65, 0x71, 0x12, 0x80, 0x01, 0x0a, 0x24, 0x6f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64,
+	0x5f, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f,
+	0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+	0x76, 0x32, 0x2e, 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70,
+	0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x20, 0x6f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65,
+	0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x7d, 0x0a, 0x23, 0x76, 0x61, 0x6c, 0x69, 0x64,
+	0x61, 0x74, 0x65, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+	0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x06,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2e, 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72,
+	0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e,
+	0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x1f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50,
+	0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68,
+	0x61, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x42, 0x0b, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x5f, 0x6f, 0x6e,
+	0x65, 0x6f, 0x66, 0x22, 0xb4, 0x04, 0x0a, 0x0b, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x70, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+	0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
+	0x73, 0x12, 0x64, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x48, 0x00, 0x52, 0x17,
+	0x67, 0x65, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x7a, 0x0a, 0x22, 0x6f, 0x66, 0x66, 0x6c, 0x6f,
+	0x61, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x6f,
+	0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+	0x76, 0x32, 0x2e, 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74,
+	0x65, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
+	0x70, 0x48, 0x00, 0x52, 0x1e, 0x6f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x69, 0x76,
+	0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x70, 0x12, 0x83, 0x01, 0x0a, 0x25, 0x6f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x5f,
+	0x72, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x6f,
+	0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x18, 0x04, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+	0x76, 0x32, 0x2e, 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70,
+	0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x52, 0x65, 0x73, 0x70, 0x48, 0x00, 0x52, 0x21, 0x6f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x52,
+	0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x80, 0x01, 0x0a, 0x24, 0x76, 0x61,
+	0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74,
+	0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x72, 0x65,
+	0x73, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65,
+	0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43,
+	0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x48, 0x00, 0x52, 0x20, 0x76, 0x61, 0x6c, 0x69,
+	0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+	0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x42, 0x0c, 0x0a, 0x0a,
+	0x72, 0x65, 0x73, 0x70, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x2a, 0xa2, 0x03, 0x0a, 0x12, 0x53,
+	0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68,
+	0x6d, 0x12, 0x1c, 0x0a, 0x18, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, 0x47,
+	0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
+	0x21, 0x0a, 0x1d, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f,
+	0x52, 0x53, 0x41, 0x5f, 0x50, 0x4b, 0x43, 0x53, 0x31, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36,
+	0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49,
+	0x47, 0x4e, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x50, 0x4b, 0x43, 0x53, 0x31, 0x5f, 0x53, 0x48, 0x41,
+	0x33, 0x38, 0x34, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c,
+	0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x50, 0x4b, 0x43, 0x53, 0x31, 0x5f,
+	0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x10, 0x03, 0x12, 0x27, 0x0a, 0x23, 0x53, 0x32, 0x41, 0x5f,
+	0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x53,
+	0x45, 0x43, 0x50, 0x32, 0x35, 0x36, 0x52, 0x31, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10,
+	0x04, 0x12, 0x27, 0x0a, 0x23, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, 0x47,
+	0x4e, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x33, 0x38, 0x34, 0x52,
+	0x31, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x05, 0x12, 0x27, 0x0a, 0x23, 0x53, 0x32,
+	0x41, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41,
+	0x5f, 0x53, 0x45, 0x43, 0x50, 0x35, 0x32, 0x31, 0x52, 0x31, 0x5f, 0x53, 0x48, 0x41, 0x35, 0x31,
+	0x32, 0x10, 0x06, 0x12, 0x24, 0x0a, 0x20, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53,
+	0x49, 0x47, 0x4e, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x50, 0x53, 0x53, 0x5f, 0x52, 0x53, 0x41, 0x45,
+	0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x07, 0x12, 0x24, 0x0a, 0x20, 0x53, 0x32, 0x41,
+	0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x50, 0x53,
+	0x53, 0x5f, 0x52, 0x53, 0x41, 0x45, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x08, 0x12,
+	0x24, 0x0a, 0x20, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f,
+	0x52, 0x53, 0x41, 0x5f, 0x50, 0x53, 0x53, 0x5f, 0x52, 0x53, 0x41, 0x45, 0x5f, 0x53, 0x48, 0x41,
+	0x35, 0x31, 0x32, 0x10, 0x09, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c,
+	0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x0a, 0x32,
+	0x57, 0x0a, 0x0a, 0x53, 0x32, 0x41, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x49, 0x0a,
+	0x0c, 0x53, 0x65, 0x74, 0x55, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x2e,
+	0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x73,
+	0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65,
+	0x73, 0x70, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68,
+	0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x73, 0x32,
+	0x61, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2f, 0x76, 0x32, 0x2f, 0x73, 0x32, 0x61, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_internal_proto_v2_s2a_s2a_proto_rawDescOnce sync.Once
+	file_internal_proto_v2_s2a_s2a_proto_rawDescData = file_internal_proto_v2_s2a_s2a_proto_rawDesc
+)
+
+func file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP() []byte {
+	file_internal_proto_v2_s2a_s2a_proto_rawDescOnce.Do(func() {
+		file_internal_proto_v2_s2a_s2a_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_v2_s2a_s2a_proto_rawDescData)
+	})
+	return file_internal_proto_v2_s2a_s2a_proto_rawDescData
+}
+
+var file_internal_proto_v2_s2a_s2a_proto_enumTypes = make([]protoimpl.EnumInfo, 6)
+var file_internal_proto_v2_s2a_s2a_proto_msgTypes = make([]protoimpl.MessageInfo, 17)
+var file_internal_proto_v2_s2a_s2a_proto_goTypes = []interface{}{
+	(SignatureAlgorithm)(0), // 0: s2a.proto.v2.SignatureAlgorithm
+	(GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate)(0), // 1: s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration.RequestClientCertificate
+	(OffloadPrivateKeyOperationReq_PrivateKeyOperation)(0),                       // 2: s2a.proto.v2.OffloadPrivateKeyOperationReq.PrivateKeyOperation
+	(OffloadResumptionKeyOperationReq_ResumptionKeyOperation)(0),                 // 3: s2a.proto.v2.OffloadResumptionKeyOperationReq.ResumptionKeyOperation
+	(ValidatePeerCertificateChainReq_VerificationMode)(0),                        // 4: s2a.proto.v2.ValidatePeerCertificateChainReq.VerificationMode
+	(ValidatePeerCertificateChainResp_ValidationResult)(0),                       // 5: s2a.proto.v2.ValidatePeerCertificateChainResp.ValidationResult
+	(*AlpnPolicy)(nil),                                     // 6: s2a.proto.v2.AlpnPolicy
+	(*AuthenticationMechanism)(nil),                        // 7: s2a.proto.v2.AuthenticationMechanism
+	(*Status)(nil),                                         // 8: s2a.proto.v2.Status
+	(*GetTlsConfigurationReq)(nil),                         // 9: s2a.proto.v2.GetTlsConfigurationReq
+	(*GetTlsConfigurationResp)(nil),                        // 10: s2a.proto.v2.GetTlsConfigurationResp
+	(*OffloadPrivateKeyOperationReq)(nil),                  // 11: s2a.proto.v2.OffloadPrivateKeyOperationReq
+	(*OffloadPrivateKeyOperationResp)(nil),                 // 12: s2a.proto.v2.OffloadPrivateKeyOperationResp
+	(*OffloadResumptionKeyOperationReq)(nil),               // 13: s2a.proto.v2.OffloadResumptionKeyOperationReq
+	(*OffloadResumptionKeyOperationResp)(nil),              // 14: s2a.proto.v2.OffloadResumptionKeyOperationResp
+	(*ValidatePeerCertificateChainReq)(nil),                // 15: s2a.proto.v2.ValidatePeerCertificateChainReq
+	(*ValidatePeerCertificateChainResp)(nil),               // 16: s2a.proto.v2.ValidatePeerCertificateChainResp
+	(*SessionReq)(nil),                                     // 17: s2a.proto.v2.SessionReq
+	(*SessionResp)(nil),                                    // 18: s2a.proto.v2.SessionResp
+	(*GetTlsConfigurationResp_ClientTlsConfiguration)(nil), // 19: s2a.proto.v2.GetTlsConfigurationResp.ClientTlsConfiguration
+	(*GetTlsConfigurationResp_ServerTlsConfiguration)(nil), // 20: s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration
+	(*ValidatePeerCertificateChainReq_ClientPeer)(nil),     // 21: s2a.proto.v2.ValidatePeerCertificateChainReq.ClientPeer
+	(*ValidatePeerCertificateChainReq_ServerPeer)(nil),     // 22: s2a.proto.v2.ValidatePeerCertificateChainReq.ServerPeer
+	(common_go_proto.AlpnProtocol)(0),                      // 23: s2a.proto.v2.AlpnProtocol
+	(*common_go_proto1.Identity)(nil),                      // 24: s2a.proto.Identity
+	(common_go_proto.ConnectionSide)(0),                    // 25: s2a.proto.v2.ConnectionSide
+	(*s2a_context_go_proto.S2AContext)(nil),                // 26: s2a.proto.v2.S2AContext
+	(common_go_proto.TLSVersion)(0),                        // 27: s2a.proto.v2.TLSVersion
+	(common_go_proto.Ciphersuite)(0),                       // 28: s2a.proto.v2.Ciphersuite
+}
+var file_internal_proto_v2_s2a_s2a_proto_depIdxs = []int32{
+	23, // 0: s2a.proto.v2.AlpnPolicy.alpn_protocols:type_name -> s2a.proto.v2.AlpnProtocol
+	24, // 1: s2a.proto.v2.AuthenticationMechanism.identity:type_name -> s2a.proto.Identity
+	25, // 2: s2a.proto.v2.GetTlsConfigurationReq.connection_side:type_name -> s2a.proto.v2.ConnectionSide
+	19, // 3: s2a.proto.v2.GetTlsConfigurationResp.client_tls_configuration:type_name -> s2a.proto.v2.GetTlsConfigurationResp.ClientTlsConfiguration
+	20, // 4: s2a.proto.v2.GetTlsConfigurationResp.server_tls_configuration:type_name -> s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration
+	2,  // 5: s2a.proto.v2.OffloadPrivateKeyOperationReq.operation:type_name -> s2a.proto.v2.OffloadPrivateKeyOperationReq.PrivateKeyOperation
+	0,  // 6: s2a.proto.v2.OffloadPrivateKeyOperationReq.signature_algorithm:type_name -> s2a.proto.v2.SignatureAlgorithm
+	3,  // 7: s2a.proto.v2.OffloadResumptionKeyOperationReq.operation:type_name -> s2a.proto.v2.OffloadResumptionKeyOperationReq.ResumptionKeyOperation
+	4,  // 8: s2a.proto.v2.ValidatePeerCertificateChainReq.mode:type_name -> s2a.proto.v2.ValidatePeerCertificateChainReq.VerificationMode
+	21, // 9: s2a.proto.v2.ValidatePeerCertificateChainReq.client_peer:type_name -> s2a.proto.v2.ValidatePeerCertificateChainReq.ClientPeer
+	22, // 10: s2a.proto.v2.ValidatePeerCertificateChainReq.server_peer:type_name -> s2a.proto.v2.ValidatePeerCertificateChainReq.ServerPeer
+	5,  // 11: s2a.proto.v2.ValidatePeerCertificateChainResp.validation_result:type_name -> s2a.proto.v2.ValidatePeerCertificateChainResp.ValidationResult
+	26, // 12: s2a.proto.v2.ValidatePeerCertificateChainResp.context:type_name -> s2a.proto.v2.S2AContext
+	24, // 13: s2a.proto.v2.SessionReq.local_identity:type_name -> s2a.proto.Identity
+	7,  // 14: s2a.proto.v2.SessionReq.authentication_mechanisms:type_name -> s2a.proto.v2.AuthenticationMechanism
+	9,  // 15: s2a.proto.v2.SessionReq.get_tls_configuration_req:type_name -> s2a.proto.v2.GetTlsConfigurationReq
+	11, // 16: s2a.proto.v2.SessionReq.offload_private_key_operation_req:type_name -> s2a.proto.v2.OffloadPrivateKeyOperationReq
+	13, // 17: s2a.proto.v2.SessionReq.offload_resumption_key_operation_req:type_name -> s2a.proto.v2.OffloadResumptionKeyOperationReq
+	15, // 18: s2a.proto.v2.SessionReq.validate_peer_certificate_chain_req:type_name -> s2a.proto.v2.ValidatePeerCertificateChainReq
+	8,  // 19: s2a.proto.v2.SessionResp.status:type_name -> s2a.proto.v2.Status
+	10, // 20: s2a.proto.v2.SessionResp.get_tls_configuration_resp:type_name -> s2a.proto.v2.GetTlsConfigurationResp
+	12, // 21: s2a.proto.v2.SessionResp.offload_private_key_operation_resp:type_name -> s2a.proto.v2.OffloadPrivateKeyOperationResp
+	14, // 22: s2a.proto.v2.SessionResp.offload_resumption_key_operation_resp:type_name -> s2a.proto.v2.OffloadResumptionKeyOperationResp
+	16, // 23: s2a.proto.v2.SessionResp.validate_peer_certificate_chain_resp:type_name -> s2a.proto.v2.ValidatePeerCertificateChainResp
+	27, // 24: s2a.proto.v2.GetTlsConfigurationResp.ClientTlsConfiguration.min_tls_version:type_name -> s2a.proto.v2.TLSVersion
+	27, // 25: s2a.proto.v2.GetTlsConfigurationResp.ClientTlsConfiguration.max_tls_version:type_name -> s2a.proto.v2.TLSVersion
+	28, // 26: s2a.proto.v2.GetTlsConfigurationResp.ClientTlsConfiguration.ciphersuites:type_name -> s2a.proto.v2.Ciphersuite
+	6,  // 27: s2a.proto.v2.GetTlsConfigurationResp.ClientTlsConfiguration.alpn_policy:type_name -> s2a.proto.v2.AlpnPolicy
+	27, // 28: s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration.min_tls_version:type_name -> s2a.proto.v2.TLSVersion
+	27, // 29: s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration.max_tls_version:type_name -> s2a.proto.v2.TLSVersion
+	28, // 30: s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration.ciphersuites:type_name -> s2a.proto.v2.Ciphersuite
+	1,  // 31: s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration.request_client_certificate:type_name -> s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration.RequestClientCertificate
+	6,  // 32: s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration.alpn_policy:type_name -> s2a.proto.v2.AlpnPolicy
+	17, // 33: s2a.proto.v2.S2AService.SetUpSession:input_type -> s2a.proto.v2.SessionReq
+	18, // 34: s2a.proto.v2.S2AService.SetUpSession:output_type -> s2a.proto.v2.SessionResp
+	34, // [34:35] is the sub-list for method output_type
+	33, // [33:34] is the sub-list for method input_type
+	33, // [33:33] is the sub-list for extension type_name
+	33, // [33:33] is the sub-list for extension extendee
+	0,  // [0:33] is the sub-list for field type_name
+}
+
+func init() { file_internal_proto_v2_s2a_s2a_proto_init() }
+func file_internal_proto_v2_s2a_s2a_proto_init() {
+	if File_internal_proto_v2_s2a_s2a_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AlpnPolicy); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AuthenticationMechanism); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Status); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetTlsConfigurationReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetTlsConfigurationResp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*OffloadPrivateKeyOperationReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*OffloadPrivateKeyOperationResp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*OffloadResumptionKeyOperationReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*OffloadResumptionKeyOperationResp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ValidatePeerCertificateChainReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ValidatePeerCertificateChainResp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SessionReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SessionResp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetTlsConfigurationResp_ClientTlsConfiguration); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetTlsConfigurationResp_ServerTlsConfiguration); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ValidatePeerCertificateChainReq_ClientPeer); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_internal_proto_v2_s2a_s2a_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ValidatePeerCertificateChainReq_ServerPeer); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	file_internal_proto_v2_s2a_s2a_proto_msgTypes[1].OneofWrappers = []interface{}{
+		(*AuthenticationMechanism_Token)(nil),
+	}
+	file_internal_proto_v2_s2a_s2a_proto_msgTypes[4].OneofWrappers = []interface{}{
+		(*GetTlsConfigurationResp_ClientTlsConfiguration_)(nil),
+		(*GetTlsConfigurationResp_ServerTlsConfiguration_)(nil),
+	}
+	file_internal_proto_v2_s2a_s2a_proto_msgTypes[5].OneofWrappers = []interface{}{
+		(*OffloadPrivateKeyOperationReq_RawBytes)(nil),
+		(*OffloadPrivateKeyOperationReq_Sha256Digest)(nil),
+		(*OffloadPrivateKeyOperationReq_Sha384Digest)(nil),
+		(*OffloadPrivateKeyOperationReq_Sha512Digest)(nil),
+	}
+	file_internal_proto_v2_s2a_s2a_proto_msgTypes[9].OneofWrappers = []interface{}{
+		(*ValidatePeerCertificateChainReq_ClientPeer_)(nil),
+		(*ValidatePeerCertificateChainReq_ServerPeer_)(nil),
+	}
+	file_internal_proto_v2_s2a_s2a_proto_msgTypes[11].OneofWrappers = []interface{}{
+		(*SessionReq_GetTlsConfigurationReq)(nil),
+		(*SessionReq_OffloadPrivateKeyOperationReq)(nil),
+		(*SessionReq_OffloadResumptionKeyOperationReq)(nil),
+		(*SessionReq_ValidatePeerCertificateChainReq)(nil),
+	}
+	file_internal_proto_v2_s2a_s2a_proto_msgTypes[12].OneofWrappers = []interface{}{
+		(*SessionResp_GetTlsConfigurationResp)(nil),
+		(*SessionResp_OffloadPrivateKeyOperationResp)(nil),
+		(*SessionResp_OffloadResumptionKeyOperationResp)(nil),
+		(*SessionResp_ValidatePeerCertificateChainResp)(nil),
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_internal_proto_v2_s2a_s2a_proto_rawDesc,
+			NumEnums:      6,
+			NumMessages:   17,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_internal_proto_v2_s2a_s2a_proto_goTypes,
+		DependencyIndexes: file_internal_proto_v2_s2a_s2a_proto_depIdxs,
+		EnumInfos:         file_internal_proto_v2_s2a_s2a_proto_enumTypes,
+		MessageInfos:      file_internal_proto_v2_s2a_s2a_proto_msgTypes,
+	}.Build()
+	File_internal_proto_v2_s2a_s2a_proto = out.File
+	file_internal_proto_v2_s2a_s2a_proto_rawDesc = nil
+	file_internal_proto_v2_s2a_s2a_proto_goTypes = nil
+	file_internal_proto_v2_s2a_s2a_proto_depIdxs = nil
+}

+ 159 - 0
vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a_grpc.pb.go

@@ -0,0 +1,159 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.3.0
+// - protoc             v3.21.12
+// source: internal/proto/v2/s2a/s2a.proto
+
+package s2a_go_proto
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.32.0 or later.
+const _ = grpc.SupportPackageIsVersion7
+
+const (
+	S2AService_SetUpSession_FullMethodName = "/s2a.proto.v2.S2AService/SetUpSession"
+)
+
+// S2AServiceClient is the client API for S2AService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type S2AServiceClient interface {
+	// SetUpSession is a bidirectional stream used by applications to offload
+	// operations from the TLS handshake.
+	SetUpSession(ctx context.Context, opts ...grpc.CallOption) (S2AService_SetUpSessionClient, error)
+}
+
+type s2AServiceClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewS2AServiceClient(cc grpc.ClientConnInterface) S2AServiceClient {
+	return &s2AServiceClient{cc}
+}
+
+func (c *s2AServiceClient) SetUpSession(ctx context.Context, opts ...grpc.CallOption) (S2AService_SetUpSessionClient, error) {
+	stream, err := c.cc.NewStream(ctx, &S2AService_ServiceDesc.Streams[0], S2AService_SetUpSession_FullMethodName, opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &s2AServiceSetUpSessionClient{stream}
+	return x, nil
+}
+
+type S2AService_SetUpSessionClient interface {
+	Send(*SessionReq) error
+	Recv() (*SessionResp, error)
+	grpc.ClientStream
+}
+
+type s2AServiceSetUpSessionClient struct {
+	grpc.ClientStream
+}
+
+func (x *s2AServiceSetUpSessionClient) Send(m *SessionReq) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *s2AServiceSetUpSessionClient) Recv() (*SessionResp, error) {
+	m := new(SessionResp)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+// S2AServiceServer is the server API for S2AService service.
+// All implementations must embed UnimplementedS2AServiceServer
+// for forward compatibility
+type S2AServiceServer interface {
+	// SetUpSession is a bidirectional stream used by applications to offload
+	// operations from the TLS handshake.
+	SetUpSession(S2AService_SetUpSessionServer) error
+	mustEmbedUnimplementedS2AServiceServer()
+}
+
+// UnimplementedS2AServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedS2AServiceServer struct {
+}
+
+func (UnimplementedS2AServiceServer) SetUpSession(S2AService_SetUpSessionServer) error {
+	return status.Errorf(codes.Unimplemented, "method SetUpSession not implemented")
+}
+func (UnimplementedS2AServiceServer) mustEmbedUnimplementedS2AServiceServer() {}
+
+// UnsafeS2AServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to S2AServiceServer will
+// result in compilation errors.
+type UnsafeS2AServiceServer interface {
+	mustEmbedUnimplementedS2AServiceServer()
+}
+
+func RegisterS2AServiceServer(s grpc.ServiceRegistrar, srv S2AServiceServer) {
+	s.RegisterService(&S2AService_ServiceDesc, srv)
+}
+
+func _S2AService_SetUpSession_Handler(srv interface{}, stream grpc.ServerStream) error {
+	return srv.(S2AServiceServer).SetUpSession(&s2AServiceSetUpSessionServer{stream})
+}
+
+type S2AService_SetUpSessionServer interface {
+	Send(*SessionResp) error
+	Recv() (*SessionReq, error)
+	grpc.ServerStream
+}
+
+type s2AServiceSetUpSessionServer struct {
+	grpc.ServerStream
+}
+
+func (x *s2AServiceSetUpSessionServer) Send(m *SessionResp) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *s2AServiceSetUpSessionServer) Recv() (*SessionReq, error) {
+	m := new(SessionReq)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+// S2AService_ServiceDesc is the grpc.ServiceDesc for S2AService service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var S2AService_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "s2a.proto.v2.S2AService",
+	HandlerType: (*S2AServiceServer)(nil),
+	Methods:     []grpc.MethodDesc{},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "SetUpSession",
+			Handler:       _S2AService_SetUpSession_Handler,
+			ServerStreams: true,
+			ClientStreams: true,
+		},
+	},
+	Metadata: "internal/proto/v2/s2a/s2a.proto",
+}

+ 34 - 0
vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aeadcrypter.go

@@ -0,0 +1,34 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package aeadcrypter provides the interface for AEAD cipher implementations
+// used by S2A's record protocol.
+package aeadcrypter
+
+// S2AAEADCrypter is the interface for an AEAD cipher used by the S2A record
+// protocol.
+type S2AAEADCrypter interface {
+	// Encrypt encrypts the plaintext and computes the tag of dst and plaintext.
+	// dst and plaintext may fully overlap or not at all.
+	Encrypt(dst, plaintext, nonce, aad []byte) ([]byte, error)
+	// Decrypt decrypts ciphertext and verifies the tag. dst and ciphertext may
+	// fully overlap or not at all.
+	Decrypt(dst, ciphertext, nonce, aad []byte) ([]byte, error)
+	// TagSize returns the tag size in bytes.
+	TagSize() int
+}

+ 70 - 0
vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aesgcm.go

@@ -0,0 +1,70 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package aeadcrypter
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+	"fmt"
+)
+
+// Supported key sizes in bytes.
+const (
+	AES128GCMKeySize = 16
+	AES256GCMKeySize = 32
+)
+
+// aesgcm is the struct that holds an AES-GCM cipher for the S2A AEAD crypter.
+type aesgcm struct {
+	aead cipher.AEAD
+}
+
+// NewAESGCM creates an AES-GCM crypter instance. Note that the key must be
+// either 128 bits or 256 bits.
+func NewAESGCM(key []byte) (S2AAEADCrypter, error) {
+	if len(key) != AES128GCMKeySize && len(key) != AES256GCMKeySize {
+		return nil, fmt.Errorf("%d or %d bytes, given: %d", AES128GCMKeySize, AES256GCMKeySize, len(key))
+	}
+	c, err := aes.NewCipher(key)
+	if err != nil {
+		return nil, err
+	}
+	a, err := cipher.NewGCM(c)
+	if err != nil {
+		return nil, err
+	}
+	return &aesgcm{aead: a}, nil
+}
+
+// Encrypt is the encryption function. dst can contain bytes at the beginning of
+// the ciphertext that will not be encrypted but will be authenticated. If dst
+// has enough capacity to hold these bytes, the ciphertext and the tag, no
+// allocation and copy operations will be performed. dst and plaintext may
+// fully overlap or not at all.
+func (s *aesgcm) Encrypt(dst, plaintext, nonce, aad []byte) ([]byte, error) {
+	return encrypt(s.aead, dst, plaintext, nonce, aad)
+}
+
+func (s *aesgcm) Decrypt(dst, ciphertext, nonce, aad []byte) ([]byte, error) {
+	return decrypt(s.aead, dst, ciphertext, nonce, aad)
+}
+
+func (s *aesgcm) TagSize() int {
+	return TagSize
+}

+ 67 - 0
vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/chachapoly.go

@@ -0,0 +1,67 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package aeadcrypter
+
+import (
+	"crypto/cipher"
+	"fmt"
+
+	"golang.org/x/crypto/chacha20poly1305"
+)
+
+// Supported key size in bytes.
+const (
+	Chacha20Poly1305KeySize = 32
+)
+
+// chachapoly is the struct that holds a CHACHA-POLY cipher for the S2A AEAD
+// crypter.
+type chachapoly struct {
+	aead cipher.AEAD
+}
+
+// NewChachaPoly creates a Chacha-Poly crypter instance. Note that the key must
+// be Chacha20Poly1305KeySize bytes in length.
+func NewChachaPoly(key []byte) (S2AAEADCrypter, error) {
+	if len(key) != Chacha20Poly1305KeySize {
+		return nil, fmt.Errorf("%d bytes, given: %d", Chacha20Poly1305KeySize, len(key))
+	}
+	c, err := chacha20poly1305.New(key)
+	if err != nil {
+		return nil, err
+	}
+	return &chachapoly{aead: c}, nil
+}
+
+// Encrypt is the encryption function. dst can contain bytes at the beginning of
+// the ciphertext that will not be encrypted but will be authenticated. If dst
+// has enough capacity to hold these bytes, the ciphertext and the tag, no
+// allocation and copy operations will be performed. dst and plaintext may
+// fully overlap or not at all.
+func (s *chachapoly) Encrypt(dst, plaintext, nonce, aad []byte) ([]byte, error) {
+	return encrypt(s.aead, dst, plaintext, nonce, aad)
+}
+
+func (s *chachapoly) Decrypt(dst, ciphertext, nonce, aad []byte) ([]byte, error) {
+	return decrypt(s.aead, dst, ciphertext, nonce, aad)
+}
+
+func (s *chachapoly) TagSize() int {
+	return TagSize
+}

+ 92 - 0
vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/common.go

@@ -0,0 +1,92 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package aeadcrypter
+
+import (
+	"crypto/cipher"
+	"fmt"
+)
+
+const (
+	// TagSize is the tag size in bytes for AES-128-GCM-SHA256,
+	// AES-256-GCM-SHA384, and CHACHA20-POLY1305-SHA256.
+	TagSize = 16
+	// NonceSize is the size of the nonce in number of bytes for
+	// AES-128-GCM-SHA256, AES-256-GCM-SHA384, and CHACHA20-POLY1305-SHA256.
+	NonceSize = 12
+	// SHA256DigestSize is the digest size of sha256 in bytes.
+	SHA256DigestSize = 32
+	// SHA384DigestSize is the digest size of sha384 in bytes.
+	SHA384DigestSize = 48
+)
+
+// sliceForAppend takes a slice and a requested number of bytes. It returns a
+// slice with the contents of the given slice followed by that many bytes and a
+// second slice that aliases into it and contains only the extra bytes. If the
+// original slice has sufficient capacity then no allocation is performed.
+func sliceForAppend(in []byte, n int) (head, tail []byte) {
+	if total := len(in) + n; cap(in) >= total {
+		head = in[:total]
+	} else {
+		head = make([]byte, total)
+		copy(head, in)
+	}
+	tail = head[len(in):]
+	return head, tail
+}
+
+// encrypt is the encryption function for an AEAD crypter. aead determines
+// the type of AEAD crypter. dst can contain bytes at the beginning of the
+// ciphertext that will not be encrypted but will be authenticated. If dst has
+// enough capacity to hold these bytes, the ciphertext and the tag, no
+// allocation and copy operations will be performed. dst and plaintext may
+// fully overlap or not at all.
+func encrypt(aead cipher.AEAD, dst, plaintext, nonce, aad []byte) ([]byte, error) {
+	if len(nonce) != NonceSize {
+		return nil, fmt.Errorf("nonce size must be %d bytes. received: %d", NonceSize, len(nonce))
+	}
+	// If we need to allocate an output buffer, we want to include space for
+	// the tag to avoid forcing the caller to reallocate as well.
+	dlen := len(dst)
+	dst, out := sliceForAppend(dst, len(plaintext)+TagSize)
+	data := out[:len(plaintext)]
+	copy(data, plaintext) // data may fully overlap plaintext
+
+	// Seal appends the ciphertext and the tag to its first argument and
+	// returns the updated slice. However, sliceForAppend above ensures that
+	// dst has enough capacity to avoid a reallocation and copy due to the
+	// append.
+	dst = aead.Seal(dst[:dlen], nonce, data, aad)
+	return dst, nil
+}
+
+// decrypt is the decryption function for an AEAD crypter, where aead determines
+// the type of AEAD crypter, and dst the destination bytes for the decrypted
+// ciphertext. The dst buffer may fully overlap with plaintext or not at all.
+func decrypt(aead cipher.AEAD, dst, ciphertext, nonce, aad []byte) ([]byte, error) {
+	if len(nonce) != NonceSize {
+		return nil, fmt.Errorf("nonce size must be %d bytes. received: %d", NonceSize, len(nonce))
+	}
+	// If dst is equal to ciphertext[:0], ciphertext storage is reused.
+	plaintext, err := aead.Open(dst, nonce, ciphertext, aad)
+	if err != nil {
+		return nil, fmt.Errorf("message auth failed: %v", err)
+	}
+	return plaintext, nil
+}

+ 98 - 0
vendor/github.com/google/s2a-go/internal/record/internal/halfconn/ciphersuite.go

@@ -0,0 +1,98 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package halfconn
+
+import (
+	"crypto/sha256"
+	"crypto/sha512"
+	"fmt"
+	"hash"
+
+	s2apb "github.com/google/s2a-go/internal/proto/common_go_proto"
+	"github.com/google/s2a-go/internal/record/internal/aeadcrypter"
+)
+
+// ciphersuite is the interface for retrieving ciphersuite-specific information
+// and utilities.
+type ciphersuite interface {
+	// keySize returns the key size in bytes. This refers to the key used by
+	// the AEAD crypter. This is derived by calling HKDF expand on the traffic
+	// secret.
+	keySize() int
+	// nonceSize returns the nonce size in bytes.
+	nonceSize() int
+	// trafficSecretSize returns the traffic secret size in bytes. This refers
+	// to the secret used to derive the traffic key and nonce, as specified in
+	// https://tools.ietf.org/html/rfc8446#section-7.
+	trafficSecretSize() int
+	// hashFunction returns the hash function for the ciphersuite.
+	hashFunction() func() hash.Hash
+	// aeadCrypter takes a key and creates an AEAD crypter for the ciphersuite
+	// using that key.
+	aeadCrypter(key []byte) (aeadcrypter.S2AAEADCrypter, error)
+}
+
+func newCiphersuite(ciphersuite s2apb.Ciphersuite) (ciphersuite, error) {
+	switch ciphersuite {
+	case s2apb.Ciphersuite_AES_128_GCM_SHA256:
+		return &aesgcm128sha256{}, nil
+	case s2apb.Ciphersuite_AES_256_GCM_SHA384:
+		return &aesgcm256sha384{}, nil
+	case s2apb.Ciphersuite_CHACHA20_POLY1305_SHA256:
+		return &chachapolysha256{}, nil
+	default:
+		return nil, fmt.Errorf("unrecognized ciphersuite: %v", ciphersuite)
+	}
+}
+
+// aesgcm128sha256 is the AES-128-GCM-SHA256 implementation of the ciphersuite
+// interface.
+type aesgcm128sha256 struct{}
+
+func (aesgcm128sha256) keySize() int                   { return aeadcrypter.AES128GCMKeySize }
+func (aesgcm128sha256) nonceSize() int                 { return aeadcrypter.NonceSize }
+func (aesgcm128sha256) trafficSecretSize() int         { return aeadcrypter.SHA256DigestSize }
+func (aesgcm128sha256) hashFunction() func() hash.Hash { return sha256.New }
+func (aesgcm128sha256) aeadCrypter(key []byte) (aeadcrypter.S2AAEADCrypter, error) {
+	return aeadcrypter.NewAESGCM(key)
+}
+
+// aesgcm256sha384 is the AES-256-GCM-SHA384 implementation of the ciphersuite
+// interface.
+type aesgcm256sha384 struct{}
+
+func (aesgcm256sha384) keySize() int                   { return aeadcrypter.AES256GCMKeySize }
+func (aesgcm256sha384) nonceSize() int                 { return aeadcrypter.NonceSize }
+func (aesgcm256sha384) trafficSecretSize() int         { return aeadcrypter.SHA384DigestSize }
+func (aesgcm256sha384) hashFunction() func() hash.Hash { return sha512.New384 }
+func (aesgcm256sha384) aeadCrypter(key []byte) (aeadcrypter.S2AAEADCrypter, error) {
+	return aeadcrypter.NewAESGCM(key)
+}
+
+// chachapolysha256 is the ChaChaPoly-SHA256 implementation of the ciphersuite
+// interface.
+type chachapolysha256 struct{}
+
+func (chachapolysha256) keySize() int                   { return aeadcrypter.Chacha20Poly1305KeySize }
+func (chachapolysha256) nonceSize() int                 { return aeadcrypter.NonceSize }
+func (chachapolysha256) trafficSecretSize() int         { return aeadcrypter.SHA256DigestSize }
+func (chachapolysha256) hashFunction() func() hash.Hash { return sha256.New }
+func (chachapolysha256) aeadCrypter(key []byte) (aeadcrypter.S2AAEADCrypter, error) {
+	return aeadcrypter.NewChachaPoly(key)
+}

+ 60 - 0
vendor/github.com/google/s2a-go/internal/record/internal/halfconn/counter.go

@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package halfconn
+
+import "errors"
+
+// counter is a 64-bit counter.
+type counter struct {
+	val           uint64
+	hasOverflowed bool
+}
+
+// newCounter creates a new counter with the initial value set to val.
+func newCounter(val uint64) counter {
+	return counter{val: val}
+}
+
+// value returns the current value of the counter.
+func (c *counter) value() (uint64, error) {
+	if c.hasOverflowed {
+		return 0, errors.New("counter has overflowed")
+	}
+	return c.val, nil
+}
+
+// increment increments the counter and checks for overflow.
+func (c *counter) increment() {
+	// If the counter is already invalid due to overflow, there is no need to
+	// increase it. We check for the hasOverflowed flag in the call to value().
+	if c.hasOverflowed {
+		return
+	}
+	c.val++
+	if c.val == 0 {
+		c.hasOverflowed = true
+	}
+}
+
+// reset sets the counter value to zero and sets the hasOverflowed flag to
+// false.
+func (c *counter) reset() {
+	c.val = 0
+	c.hasOverflowed = false
+}

+ 59 - 0
vendor/github.com/google/s2a-go/internal/record/internal/halfconn/expander.go

@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package halfconn
+
+import (
+	"fmt"
+	"hash"
+
+	"golang.org/x/crypto/hkdf"
+)
+
+// hkdfExpander is the interface for the HKDF expansion function; see
+// https://tools.ietf.org/html/rfc5869 for details. its use in TLS 1.3 is
+// specified in https://tools.ietf.org/html/rfc8446#section-7.2
+type hkdfExpander interface {
+	// expand takes a secret, a label, and the output length in bytes, and
+	// returns the resulting expanded key.
+	expand(secret, label []byte, length int) ([]byte, error)
+}
+
+// defaultHKDFExpander is the default HKDF expander which uses Go's crypto/hkdf
+// for HKDF expansion.
+type defaultHKDFExpander struct {
+	h func() hash.Hash
+}
+
+// newDefaultHKDFExpander creates an instance of the default HKDF expander
+// using the given hash function.
+func newDefaultHKDFExpander(h func() hash.Hash) hkdfExpander {
+	return &defaultHKDFExpander{h: h}
+}
+
+func (d *defaultHKDFExpander) expand(secret, label []byte, length int) ([]byte, error) {
+	outBuf := make([]byte, length)
+	n, err := hkdf.Expand(d.h, secret, label).Read(outBuf)
+	if err != nil {
+		return nil, fmt.Errorf("hkdf.Expand.Read failed with error: %v", err)
+	}
+	if n < length {
+		return nil, fmt.Errorf("hkdf.Expand.Read returned unexpected length, got %d, want %d", n, length)
+	}
+	return outBuf, nil
+}

+ 193 - 0
vendor/github.com/google/s2a-go/internal/record/internal/halfconn/halfconn.go

@@ -0,0 +1,193 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package halfconn manages the inbound or outbound traffic of a TLS 1.3
+// connection.
+package halfconn
+
+import (
+	"fmt"
+	"sync"
+
+	s2apb "github.com/google/s2a-go/internal/proto/common_go_proto"
+	"github.com/google/s2a-go/internal/record/internal/aeadcrypter"
+	"golang.org/x/crypto/cryptobyte"
+)
+
+// The constants below were taken from Section 7.2 and 7.3 in
+// https://tools.ietf.org/html/rfc8446#section-7. They are used as the label
+// in HKDF-Expand-Label.
+const (
+	tls13Key    = "tls13 key"
+	tls13Nonce  = "tls13 iv"
+	tls13Update = "tls13 traffic upd"
+)
+
+// S2AHalfConnection stores the state of the TLS 1.3 connection in the
+// inbound or outbound direction.
+type S2AHalfConnection struct {
+	cs       ciphersuite
+	expander hkdfExpander
+	// mutex guards sequence, aeadCrypter, trafficSecret, and nonce.
+	mutex         sync.Mutex
+	aeadCrypter   aeadcrypter.S2AAEADCrypter
+	sequence      counter
+	trafficSecret []byte
+	nonce         []byte
+}
+
+// New creates a new instance of S2AHalfConnection given a ciphersuite and a
+// traffic secret.
+func New(ciphersuite s2apb.Ciphersuite, trafficSecret []byte, sequence uint64) (*S2AHalfConnection, error) {
+	cs, err := newCiphersuite(ciphersuite)
+	if err != nil {
+		return nil, fmt.Errorf("failed to create new ciphersuite: %v", ciphersuite)
+	}
+	if cs.trafficSecretSize() != len(trafficSecret) {
+		return nil, fmt.Errorf("supplied traffic secret must be %v bytes, given: %v bytes", cs.trafficSecretSize(), len(trafficSecret))
+	}
+
+	hc := &S2AHalfConnection{cs: cs, expander: newDefaultHKDFExpander(cs.hashFunction()), sequence: newCounter(sequence), trafficSecret: trafficSecret}
+	if err = hc.updateCrypterAndNonce(hc.trafficSecret); err != nil {
+		return nil, fmt.Errorf("failed to create half connection using traffic secret: %v", err)
+	}
+
+	return hc, nil
+}
+
+// Encrypt encrypts the plaintext and computes the tag of dst and plaintext.
+// dst and plaintext may fully overlap or not at all. Note that the sequence
+// number will still be incremented on failure, unless the sequence has
+// overflowed.
+func (hc *S2AHalfConnection) Encrypt(dst, plaintext, aad []byte) ([]byte, error) {
+	hc.mutex.Lock()
+	sequence, err := hc.getAndIncrementSequence()
+	if err != nil {
+		hc.mutex.Unlock()
+		return nil, err
+	}
+	nonce := hc.maskedNonce(sequence)
+	crypter := hc.aeadCrypter
+	hc.mutex.Unlock()
+	return crypter.Encrypt(dst, plaintext, nonce, aad)
+}
+
+// Decrypt decrypts ciphertext and verifies the tag. dst and ciphertext may
+// fully overlap or not at all. Note that the sequence number will still be
+// incremented on failure, unless the sequence has overflowed.
+func (hc *S2AHalfConnection) Decrypt(dst, ciphertext, aad []byte) ([]byte, error) {
+	hc.mutex.Lock()
+	sequence, err := hc.getAndIncrementSequence()
+	if err != nil {
+		hc.mutex.Unlock()
+		return nil, err
+	}
+	nonce := hc.maskedNonce(sequence)
+	crypter := hc.aeadCrypter
+	hc.mutex.Unlock()
+	return crypter.Decrypt(dst, ciphertext, nonce, aad)
+}
+
+// UpdateKey advances the traffic secret key, as specified in
+// https://tools.ietf.org/html/rfc8446#section-7.2. In addition, it derives
+// a new key and nonce, and resets the sequence number.
+func (hc *S2AHalfConnection) UpdateKey() error {
+	hc.mutex.Lock()
+	defer hc.mutex.Unlock()
+
+	var err error
+	hc.trafficSecret, err = hc.deriveSecret(hc.trafficSecret, []byte(tls13Update), hc.cs.trafficSecretSize())
+	if err != nil {
+		return fmt.Errorf("failed to derive traffic secret: %v", err)
+	}
+
+	if err = hc.updateCrypterAndNonce(hc.trafficSecret); err != nil {
+		return fmt.Errorf("failed to update half connection: %v", err)
+	}
+
+	hc.sequence.reset()
+	return nil
+}
+
+// TagSize returns the tag size in bytes of the underlying AEAD crypter.
+func (hc *S2AHalfConnection) TagSize() int {
+	return hc.aeadCrypter.TagSize()
+}
+
+// updateCrypterAndNonce takes a new traffic secret and updates the crypter
+// and nonce. Note that the mutex must be held while calling this function.
+func (hc *S2AHalfConnection) updateCrypterAndNonce(newTrafficSecret []byte) error {
+	key, err := hc.deriveSecret(newTrafficSecret, []byte(tls13Key), hc.cs.keySize())
+	if err != nil {
+		return fmt.Errorf("failed to update key: %v", err)
+	}
+
+	hc.nonce, err = hc.deriveSecret(newTrafficSecret, []byte(tls13Nonce), hc.cs.nonceSize())
+	if err != nil {
+		return fmt.Errorf("failed to update nonce: %v", err)
+	}
+
+	hc.aeadCrypter, err = hc.cs.aeadCrypter(key)
+	if err != nil {
+		return fmt.Errorf("failed to update AEAD crypter: %v", err)
+	}
+	return nil
+}
+
+// getAndIncrement returns the current sequence number and increments it. Note
+// that the mutex must be held while calling this function.
+func (hc *S2AHalfConnection) getAndIncrementSequence() (uint64, error) {
+	sequence, err := hc.sequence.value()
+	if err != nil {
+		return 0, err
+	}
+	hc.sequence.increment()
+	return sequence, nil
+}
+
+// maskedNonce creates a copy of the nonce that is masked with the sequence
+// number. Note that the mutex must be held while calling this function.
+func (hc *S2AHalfConnection) maskedNonce(sequence uint64) []byte {
+	const uint64Size = 8
+	nonce := make([]byte, len(hc.nonce))
+	copy(nonce, hc.nonce)
+	for i := 0; i < uint64Size; i++ {
+		nonce[aeadcrypter.NonceSize-uint64Size+i] ^= byte(sequence >> uint64(56-uint64Size*i))
+	}
+	return nonce
+}
+
+// deriveSecret implements the Derive-Secret function, as specified in
+// https://tools.ietf.org/html/rfc8446#section-7.1.
+func (hc *S2AHalfConnection) deriveSecret(secret, label []byte, length int) ([]byte, error) {
+	var hkdfLabel cryptobyte.Builder
+	hkdfLabel.AddUint16(uint16(length))
+	hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+		b.AddBytes(label)
+	})
+	// Append an empty `Context` field to the label, as specified in the RFC.
+	// The half connection does not use the `Context` field.
+	hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+		b.AddBytes([]byte(""))
+	})
+	hkdfLabelBytes, err := hkdfLabel.Bytes()
+	if err != nil {
+		return nil, fmt.Errorf("deriveSecret failed: %v", err)
+	}
+	return hc.expander.expand(secret, hkdfLabelBytes, length)
+}

+ 757 - 0
vendor/github.com/google/s2a-go/internal/record/record.go

@@ -0,0 +1,757 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package record implements the TLS 1.3 record protocol used by the S2A
+// transport credentials.
+package record
+
+import (
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"math"
+	"net"
+	"sync"
+
+	commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
+	"github.com/google/s2a-go/internal/record/internal/halfconn"
+	"github.com/google/s2a-go/internal/tokenmanager"
+	"google.golang.org/grpc/grpclog"
+)
+
+// recordType is the `ContentType` as described in
+// https://tools.ietf.org/html/rfc8446#section-5.1.
+type recordType byte
+
+const (
+	alert           recordType = 21
+	handshake       recordType = 22
+	applicationData recordType = 23
+)
+
+// keyUpdateRequest is the `KeyUpdateRequest` as described in
+// https://tools.ietf.org/html/rfc8446#section-4.6.3.
+type keyUpdateRequest byte
+
+const (
+	updateNotRequested keyUpdateRequest = 0
+	updateRequested    keyUpdateRequest = 1
+)
+
+// alertDescription is the `AlertDescription` as described in
+// https://tools.ietf.org/html/rfc8446#section-6.
+type alertDescription byte
+
+const (
+	closeNotify alertDescription = 0
+)
+
+// sessionTicketState is used to determine whether session tickets have not yet
+// been received, are in the process of being received, or have finished
+// receiving.
+type sessionTicketState byte
+
+const (
+	ticketsNotYetReceived sessionTicketState = 0
+	receivingTickets      sessionTicketState = 1
+	notReceivingTickets   sessionTicketState = 2
+)
+
+const (
+	// The TLS 1.3-specific constants below (tlsRecordMaxPlaintextSize,
+	// tlsRecordHeaderSize, tlsRecordTypeSize) were taken from
+	// https://tools.ietf.org/html/rfc8446#section-5.1.
+
+	// tlsRecordMaxPlaintextSize is the maximum size in bytes of the plaintext
+	// in a single TLS 1.3 record.
+	tlsRecordMaxPlaintextSize = 16384 // 2^14
+	// tlsRecordTypeSize is the size in bytes of the TLS 1.3 record type.
+	tlsRecordTypeSize = 1
+	// tlsTagSize is the size in bytes of the tag of the following three
+	// ciphersuites: AES-128-GCM-SHA256, AES-256-GCM-SHA384,
+	// CHACHA20-POLY1305-SHA256.
+	tlsTagSize = 16
+	// tlsRecordMaxPayloadSize is the maximum size in bytes of the payload in a
+	// single TLS 1.3 record. This is the maximum size of the plaintext plus the
+	// record type byte and 16 bytes of the tag.
+	tlsRecordMaxPayloadSize = tlsRecordMaxPlaintextSize + tlsRecordTypeSize + tlsTagSize
+	// tlsRecordHeaderTypeSize is the size in bytes of the TLS 1.3 record
+	// header type.
+	tlsRecordHeaderTypeSize = 1
+	// tlsRecordHeaderLegacyRecordVersionSize is the size in bytes of the TLS
+	// 1.3 record header legacy record version.
+	tlsRecordHeaderLegacyRecordVersionSize = 2
+	// tlsRecordHeaderPayloadLengthSize is the size in bytes of the TLS 1.3
+	// record header payload length.
+	tlsRecordHeaderPayloadLengthSize = 2
+	// tlsRecordHeaderSize is the size in bytes of the TLS 1.3 record header.
+	tlsRecordHeaderSize = tlsRecordHeaderTypeSize + tlsRecordHeaderLegacyRecordVersionSize + tlsRecordHeaderPayloadLengthSize
+	// tlsRecordMaxSize
+	tlsRecordMaxSize = tlsRecordMaxPayloadSize + tlsRecordHeaderSize
+	// tlsApplicationData is the application data type of the TLS 1.3 record
+	// header.
+	tlsApplicationData = 23
+	// tlsLegacyRecordVersion is the legacy record version of the TLS record.
+	tlsLegacyRecordVersion = 3
+	// tlsAlertSize is the size in bytes of an alert of TLS 1.3.
+	tlsAlertSize = 2
+)
+
+const (
+	// These are TLS 1.3 handshake-specific constants.
+
+	// tlsHandshakeNewSessionTicketType is the prefix of a handshake new session
+	// ticket message of TLS 1.3.
+	tlsHandshakeNewSessionTicketType = 4
+	// tlsHandshakeKeyUpdateType is the prefix of a handshake key update message
+	// of TLS 1.3.
+	tlsHandshakeKeyUpdateType = 24
+	// tlsHandshakeMsgTypeSize is the size in bytes of the TLS 1.3 handshake
+	// message type field.
+	tlsHandshakeMsgTypeSize = 1
+	// tlsHandshakeLengthSize is the size in bytes of the TLS 1.3 handshake
+	// message length field.
+	tlsHandshakeLengthSize = 3
+	// tlsHandshakeKeyUpdateMsgSize is the size in bytes of the TLS 1.3
+	// handshake key update message.
+	tlsHandshakeKeyUpdateMsgSize = 1
+	// tlsHandshakePrefixSize is the size in bytes of the prefix of the TLS 1.3
+	// handshake message.
+	tlsHandshakePrefixSize = 4
+	// tlsMaxSessionTicketSize is the maximum size of a NewSessionTicket message
+	// in TLS 1.3. This is the sum of the max sizes of all the fields in the
+	// NewSessionTicket struct specified in
+	// https://tools.ietf.org/html/rfc8446#section-4.6.1.
+	tlsMaxSessionTicketSize = 131338
+)
+
+const (
+	// outBufMaxRecords is the maximum number of records that can fit in the
+	// ourRecordsBuf buffer.
+	outBufMaxRecords = 16
+	// outBufMaxSize is the maximum size (in bytes) of the outRecordsBuf buffer.
+	outBufMaxSize = outBufMaxRecords * tlsRecordMaxSize
+	// maxAllowedTickets is the maximum number of session tickets that are
+	// allowed. The number of tickets are limited to ensure that the size of the
+	// ticket queue does not grow indefinitely. S2A also keeps a limit on the
+	// number of tickets that it caches.
+	maxAllowedTickets = 5
+)
+
+// preConstructedKeyUpdateMsg holds the key update message. This is needed as an
+// optimization so that the same message does not need to be constructed every
+// time a key update message is sent.
+var preConstructedKeyUpdateMsg = buildKeyUpdateRequest()
+
+// conn represents a secured TLS connection. It implements the net.Conn
+// interface.
+type conn struct {
+	net.Conn
+	// inConn is the half connection responsible for decrypting incoming bytes.
+	inConn *halfconn.S2AHalfConnection
+	// outConn is the half connection responsible for encrypting outgoing bytes.
+	outConn *halfconn.S2AHalfConnection
+	// pendingApplicationData holds data that has been read from the connection
+	// and decrypted, but has not yet been returned by Read.
+	pendingApplicationData []byte
+	// unusedBuf holds data read from the network that has not yet been
+	// decrypted. This data might not consist of a complete record. It may
+	// consist of several records, the last of which could be incomplete.
+	unusedBuf []byte
+	// outRecordsBuf is a buffer used to store outgoing TLS records before
+	// they are written to the network.
+	outRecordsBuf []byte
+	// nextRecord stores the next record info in the unusedBuf buffer.
+	nextRecord []byte
+	// overheadSize is the overhead size in bytes of each TLS 1.3 record, which
+	// is computed as overheadSize = header size + record type byte + tag size.
+	// Note that there is no padding by zeros in the overhead calculation.
+	overheadSize int
+	// readMutex guards against concurrent calls to Read. This is required since
+	// Close may be called during a Read.
+	readMutex sync.Mutex
+	// writeMutex guards against concurrent calls to Write. This is required
+	// since Close may be called during a Write, and also because a key update
+	// message may be written during a Read.
+	writeMutex sync.Mutex
+	// handshakeBuf holds handshake messages while they are being processed.
+	handshakeBuf []byte
+	// ticketState is the current processing state of the session tickets.
+	ticketState sessionTicketState
+	// sessionTickets holds the completed session tickets until they are sent to
+	// the handshaker service for processing.
+	sessionTickets [][]byte
+	// ticketSender sends session tickets to the S2A handshaker service.
+	ticketSender s2aTicketSender
+	// callComplete is a channel that blocks closing the record protocol until a
+	// pending call to the S2A completes.
+	callComplete chan bool
+}
+
+// ConnParameters holds the parameters used for creating a new conn object.
+type ConnParameters struct {
+	// NetConn is the TCP connection to the peer. This parameter is required.
+	NetConn net.Conn
+	// Ciphersuite is the TLS ciphersuite negotiated by the S2A handshaker
+	// service. This parameter is required.
+	Ciphersuite commonpb.Ciphersuite
+	// TLSVersion is the TLS version number negotiated by the S2A handshaker
+	// service. This parameter is required.
+	TLSVersion commonpb.TLSVersion
+	// InTrafficSecret is the traffic secret used to derive the session key for
+	// the inbound direction. This parameter is required.
+	InTrafficSecret []byte
+	// OutTrafficSecret is the traffic secret used to derive the session key
+	// for the outbound direction. This parameter is required.
+	OutTrafficSecret []byte
+	// UnusedBuf is the data read from the network that has not yet been
+	// decrypted. This parameter is optional. If not provided, then no
+	// application data was sent in the same flight of messages as the final
+	// handshake message.
+	UnusedBuf []byte
+	// InSequence is the sequence number of the next, incoming, TLS record.
+	// This parameter is required.
+	InSequence uint64
+	// OutSequence is the sequence number of the next, outgoing, TLS record.
+	// This parameter is required.
+	OutSequence uint64
+	// HSAddr stores the address of the S2A handshaker service. This parameter
+	// is optional. If not provided, then TLS resumption is disabled.
+	HSAddr string
+	// ConnectionId is the connection identifier that was created and sent by
+	// S2A at the end of a handshake.
+	ConnectionID uint64
+	// LocalIdentity is the local identity that was used by S2A during session
+	// setup and included in the session result.
+	LocalIdentity *commonpb.Identity
+	// EnsureProcessSessionTickets allows users to wait and ensure that all
+	// available session tickets are sent to S2A before a process completes.
+	EnsureProcessSessionTickets *sync.WaitGroup
+}
+
+// NewConn creates a TLS record protocol that wraps the TCP connection.
+func NewConn(o *ConnParameters) (net.Conn, error) {
+	if o == nil {
+		return nil, errors.New("conn options must not be nil")
+	}
+	if o.TLSVersion != commonpb.TLSVersion_TLS1_3 {
+		return nil, errors.New("TLS version must be TLS 1.3")
+	}
+
+	inConn, err := halfconn.New(o.Ciphersuite, o.InTrafficSecret, o.InSequence)
+	if err != nil {
+		return nil, fmt.Errorf("failed to create inbound half connection: %v", err)
+	}
+	outConn, err := halfconn.New(o.Ciphersuite, o.OutTrafficSecret, o.OutSequence)
+	if err != nil {
+		return nil, fmt.Errorf("failed to create outbound half connection: %v", err)
+	}
+
+	// The tag size for the in/out connections should be the same.
+	overheadSize := tlsRecordHeaderSize + tlsRecordTypeSize + inConn.TagSize()
+	var unusedBuf []byte
+	if o.UnusedBuf == nil {
+		// We pre-allocate unusedBuf to be of size
+		// 2*tlsRecordMaxSize-1 during initialization. We only read from the
+		// network into unusedBuf when unusedBuf does not contain a complete
+		// record and the incomplete record is at most tlsRecordMaxSize-1
+		// (bytes). And we read at most tlsRecordMaxSize bytes of data from the
+		// network into unusedBuf at one time. Therefore, 2*tlsRecordMaxSize-1
+		// is large enough to buffer data read from the network.
+		unusedBuf = make([]byte, 0, 2*tlsRecordMaxSize-1)
+	} else {
+		unusedBuf = make([]byte, len(o.UnusedBuf))
+		copy(unusedBuf, o.UnusedBuf)
+	}
+
+	tokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager()
+	if err != nil {
+		grpclog.Infof("failed to create single token access token manager: %v", err)
+	}
+
+	s2aConn := &conn{
+		Conn:          o.NetConn,
+		inConn:        inConn,
+		outConn:       outConn,
+		unusedBuf:     unusedBuf,
+		outRecordsBuf: make([]byte, tlsRecordMaxSize),
+		nextRecord:    unusedBuf,
+		overheadSize:  overheadSize,
+		ticketState:   ticketsNotYetReceived,
+		// Pre-allocate the buffer for one session ticket message and the max
+		// plaintext size. This is the largest size that handshakeBuf will need
+		// to hold. The largest incomplete handshake message is the
+		// [handshake header size] + [max session ticket size] - 1.
+		// Then, tlsRecordMaxPlaintextSize is the maximum size that will be
+		// appended to the handshakeBuf before the handshake message is
+		// completed. Therefore, the buffer size below should be large enough to
+		// buffer any handshake messages.
+		handshakeBuf: make([]byte, 0, tlsHandshakePrefixSize+tlsMaxSessionTicketSize+tlsRecordMaxPlaintextSize-1),
+		ticketSender: &ticketSender{
+			hsAddr:                      o.HSAddr,
+			connectionID:                o.ConnectionID,
+			localIdentity:               o.LocalIdentity,
+			tokenManager:                tokenManager,
+			ensureProcessSessionTickets: o.EnsureProcessSessionTickets,
+		},
+		callComplete: make(chan bool),
+	}
+	return s2aConn, nil
+}
+
+// Read reads and decrypts a TLS 1.3 record from the underlying connection, and
+// copies any application data received from the peer into b. If the size of the
+// payload is greater than len(b), Read retains the remaining bytes in an
+// internal buffer, and subsequent calls to Read will read from this buffer
+// until it is exhausted. At most 1 TLS record worth of application data is
+// written to b for each call to Read.
+//
+// Note that for the user to efficiently call this method, the user should
+// ensure that the buffer b is allocated such that the buffer does not have any
+// unused segments. This can be done by calling Read via io.ReadFull, which
+// continually calls Read until the specified buffer has been filled. Also note
+// that the user should close the connection via Close() if an error is thrown
+// by a call to Read.
+func (p *conn) Read(b []byte) (n int, err error) {
+	p.readMutex.Lock()
+	defer p.readMutex.Unlock()
+	// Check if p.pendingApplication data has leftover application data from
+	// the previous call to Read.
+	if len(p.pendingApplicationData) == 0 {
+		// Read a full record from the wire.
+		record, err := p.readFullRecord()
+		if err != nil {
+			return 0, err
+		}
+		// Now we have a complete record, so split the header and validate it
+		// The TLS record is split into 2 pieces: the record header and the
+		// payload. The payload has the following form:
+		// [payload] = [ciphertext of application data]
+		//           + [ciphertext of record type byte]
+		//           + [(optionally) ciphertext of padding by zeros]
+		//           + [tag]
+		header, payload, err := splitAndValidateHeader(record)
+		if err != nil {
+			return 0, err
+		}
+		// Decrypt the ciphertext.
+		p.pendingApplicationData, err = p.inConn.Decrypt(payload[:0], payload, header)
+		if err != nil {
+			return 0, err
+		}
+		// Remove the padding by zeros and the record type byte from the
+		// p.pendingApplicationData buffer.
+		msgType, err := p.stripPaddingAndType()
+		if err != nil {
+			return 0, err
+		}
+		// Check that the length of the plaintext after stripping the padding
+		// and record type byte is under the maximum plaintext size.
+		if len(p.pendingApplicationData) > tlsRecordMaxPlaintextSize {
+			return 0, errors.New("plaintext size larger than maximum")
+		}
+		// The expected message types are application data, alert, and
+		// handshake. For application data, the bytes are directly copied into
+		// b. For an alert, the type of the alert is checked and the connection
+		// is closed on a close notify alert. For a handshake message, the
+		// handshake message type is checked. The handshake message type can be
+		// a key update type, for which we advance the traffic secret, and a
+		// new session ticket type, for which we send the received ticket to S2A
+		// for processing.
+		switch msgType {
+		case applicationData:
+			if len(p.handshakeBuf) > 0 {
+				return 0, errors.New("application data received while processing fragmented handshake messages")
+			}
+			if p.ticketState == receivingTickets {
+				p.ticketState = notReceivingTickets
+				grpclog.Infof("Sending session tickets to S2A.")
+				p.ticketSender.sendTicketsToS2A(p.sessionTickets, p.callComplete)
+			}
+		case alert:
+			return 0, p.handleAlertMessage()
+		case handshake:
+			if err = p.handleHandshakeMessage(); err != nil {
+				return 0, err
+			}
+			return 0, nil
+		default:
+			return 0, errors.New("unknown record type")
+		}
+	}
+	// Write as much application data as possible to b, the output buffer.
+	n = copy(b, p.pendingApplicationData)
+	p.pendingApplicationData = p.pendingApplicationData[n:]
+	return n, nil
+}
+
+// Write divides b into segments of size tlsRecordMaxPlaintextSize, builds a
+// TLS 1.3 record (of type "application data") from each segment, and sends
+// the record to the peer. It returns the number of plaintext bytes that were
+// successfully sent to the peer.
+func (p *conn) Write(b []byte) (n int, err error) {
+	p.writeMutex.Lock()
+	defer p.writeMutex.Unlock()
+	return p.writeTLSRecord(b, tlsApplicationData)
+}
+
+// writeTLSRecord divides b into segments of size maxPlaintextBytesPerRecord,
+// builds a TLS 1.3 record (of type recordType) from each segment, and sends
+// the record to the peer. It returns the number of plaintext bytes that were
+// successfully sent to the peer.
+func (p *conn) writeTLSRecord(b []byte, recordType byte) (n int, err error) {
+	// Create a record of only header, record type, and tag if given empty
+	// byte array.
+	if len(b) == 0 {
+		recordEndIndex, _, err := p.buildRecord(b, recordType, 0)
+		if err != nil {
+			return 0, err
+		}
+
+		// Write the bytes stored in outRecordsBuf to p.Conn. Since we return
+		// the number of plaintext bytes written without overhead, we will
+		// always return 0 while p.Conn.Write returns the entire record length.
+		_, err = p.Conn.Write(p.outRecordsBuf[:recordEndIndex])
+		return 0, err
+	}
+
+	numRecords := int(math.Ceil(float64(len(b)) / float64(tlsRecordMaxPlaintextSize)))
+	totalRecordsSize := len(b) + numRecords*p.overheadSize
+	partialBSize := len(b)
+	if totalRecordsSize > outBufMaxSize {
+		totalRecordsSize = outBufMaxSize
+		partialBSize = outBufMaxRecords * tlsRecordMaxPlaintextSize
+	}
+	if len(p.outRecordsBuf) < totalRecordsSize {
+		p.outRecordsBuf = make([]byte, totalRecordsSize)
+	}
+	for bStart := 0; bStart < len(b); bStart += partialBSize {
+		bEnd := bStart + partialBSize
+		if bEnd > len(b) {
+			bEnd = len(b)
+		}
+		partialB := b[bStart:bEnd]
+		recordEndIndex := 0
+		for len(partialB) > 0 {
+			recordEndIndex, partialB, err = p.buildRecord(partialB, recordType, recordEndIndex)
+			if err != nil {
+				// Return the amount of bytes written prior to the error.
+				return bStart, err
+			}
+		}
+		// Write the bytes stored in outRecordsBuf to p.Conn. If there is an
+		// error, calculate the total number of plaintext bytes of complete
+		// records successfully written to the peer and return it.
+		nn, err := p.Conn.Write(p.outRecordsBuf[:recordEndIndex])
+		if err != nil {
+			numberOfCompletedRecords := int(math.Floor(float64(nn) / float64(tlsRecordMaxSize)))
+			return bStart + numberOfCompletedRecords*tlsRecordMaxPlaintextSize, err
+		}
+	}
+	return len(b), nil
+}
+
+// buildRecord builds a TLS 1.3 record of type recordType from plaintext,
+// and writes the record to outRecordsBuf at recordStartIndex. The record will
+// have at most tlsRecordMaxPlaintextSize bytes of payload. It returns the
+// index of outRecordsBuf where the current record ends, as well as any
+// remaining plaintext bytes.
+func (p *conn) buildRecord(plaintext []byte, recordType byte, recordStartIndex int) (n int, remainingPlaintext []byte, err error) {
+	// Construct the payload, which consists of application data and record type.
+	dataLen := len(plaintext)
+	if dataLen > tlsRecordMaxPlaintextSize {
+		dataLen = tlsRecordMaxPlaintextSize
+	}
+	remainingPlaintext = plaintext[dataLen:]
+	newRecordBuf := p.outRecordsBuf[recordStartIndex:]
+
+	copy(newRecordBuf[tlsRecordHeaderSize:], plaintext[:dataLen])
+	newRecordBuf[tlsRecordHeaderSize+dataLen] = recordType
+	payload := newRecordBuf[tlsRecordHeaderSize : tlsRecordHeaderSize+dataLen+1] // 1 is for the recordType.
+	// Construct the header.
+	newRecordBuf[0] = tlsApplicationData
+	newRecordBuf[1] = tlsLegacyRecordVersion
+	newRecordBuf[2] = tlsLegacyRecordVersion
+	binary.BigEndian.PutUint16(newRecordBuf[3:], uint16(len(payload)+tlsTagSize))
+	header := newRecordBuf[:tlsRecordHeaderSize]
+
+	// Encrypt the payload using header as aad.
+	encryptedPayload, err := p.outConn.Encrypt(newRecordBuf[tlsRecordHeaderSize:][:0], payload, header)
+	if err != nil {
+		return 0, plaintext, err
+	}
+	recordStartIndex += len(header) + len(encryptedPayload)
+	return recordStartIndex, remainingPlaintext, nil
+}
+
+func (p *conn) Close() error {
+	p.readMutex.Lock()
+	defer p.readMutex.Unlock()
+	p.writeMutex.Lock()
+	defer p.writeMutex.Unlock()
+	// If p.ticketState is equal to notReceivingTickets, then S2A has
+	// been sent a flight of session tickets, and we must wait for the
+	// call to S2A to complete before closing the record protocol.
+	if p.ticketState == notReceivingTickets {
+		<-p.callComplete
+		grpclog.Infof("Safe to close the connection because sending tickets to S2A is (already) complete.")
+	}
+	return p.Conn.Close()
+}
+
+// stripPaddingAndType strips the padding by zeros and record type from
+// p.pendingApplicationData and returns the record type. Note that
+// p.pendingApplicationData should be of the form:
+// [application data] + [record type byte] + [trailing zeros]
+func (p *conn) stripPaddingAndType() (recordType, error) {
+	if len(p.pendingApplicationData) == 0 {
+		return 0, errors.New("application data had length 0")
+	}
+	i := len(p.pendingApplicationData) - 1
+	// Search for the index of the record type byte.
+	for i > 0 {
+		if p.pendingApplicationData[i] != 0 {
+			break
+		}
+		i--
+	}
+	rt := recordType(p.pendingApplicationData[i])
+	p.pendingApplicationData = p.pendingApplicationData[:i]
+	return rt, nil
+}
+
+// readFullRecord reads from the wire until a record is completed and returns
+// the full record.
+func (p *conn) readFullRecord() (fullRecord []byte, err error) {
+	fullRecord, p.nextRecord, err = parseReadBuffer(p.nextRecord, tlsRecordMaxPayloadSize)
+	if err != nil {
+		return nil, err
+	}
+	// Check whether the next record to be decrypted has been completely
+	// received.
+	if len(fullRecord) == 0 {
+		copy(p.unusedBuf, p.nextRecord)
+		p.unusedBuf = p.unusedBuf[:len(p.nextRecord)]
+		// Always copy next incomplete record to the beginning of the
+		// unusedBuf buffer and reset nextRecord to it.
+		p.nextRecord = p.unusedBuf
+	}
+	// Keep reading from the wire until we have a complete record.
+	for len(fullRecord) == 0 {
+		if len(p.unusedBuf) == cap(p.unusedBuf) {
+			tmp := make([]byte, len(p.unusedBuf), cap(p.unusedBuf)+tlsRecordMaxSize)
+			copy(tmp, p.unusedBuf)
+			p.unusedBuf = tmp
+		}
+		n, err := p.Conn.Read(p.unusedBuf[len(p.unusedBuf):min(cap(p.unusedBuf), len(p.unusedBuf)+tlsRecordMaxSize)])
+		if err != nil {
+			return nil, err
+		}
+		p.unusedBuf = p.unusedBuf[:len(p.unusedBuf)+n]
+		fullRecord, p.nextRecord, err = parseReadBuffer(p.unusedBuf, tlsRecordMaxPayloadSize)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return fullRecord, nil
+}
+
+// parseReadBuffer parses the provided buffer and returns a full record and any
+// remaining bytes in that buffer. If the record is incomplete, nil is returned
+// for the first return value and the given byte buffer is returned for the
+// second return value. The length of the payload specified by the header should
+// not be greater than maxLen, otherwise an error is returned. Note that this
+// function does not allocate or copy any buffers.
+func parseReadBuffer(b []byte, maxLen uint16) (fullRecord, remaining []byte, err error) {
+	// If the header is not complete, return the provided buffer as remaining
+	// buffer.
+	if len(b) < tlsRecordHeaderSize {
+		return nil, b, nil
+	}
+	msgLenField := b[tlsRecordHeaderTypeSize+tlsRecordHeaderLegacyRecordVersionSize : tlsRecordHeaderSize]
+	length := binary.BigEndian.Uint16(msgLenField)
+	if length > maxLen {
+		return nil, nil, fmt.Errorf("record length larger than the limit %d", maxLen)
+	}
+	if len(b) < int(length)+tlsRecordHeaderSize {
+		// Record is not complete yet.
+		return nil, b, nil
+	}
+	return b[:tlsRecordHeaderSize+length], b[tlsRecordHeaderSize+length:], nil
+}
+
+// splitAndValidateHeader splits the header from the payload in the TLS 1.3
+// record and returns them. Note that the header is checked for validity, and an
+// error is returned when an invalid header is parsed. Also note that this
+// function does not allocate or copy any buffers.
+func splitAndValidateHeader(record []byte) (header, payload []byte, err error) {
+	if len(record) < tlsRecordHeaderSize {
+		return nil, nil, fmt.Errorf("record was smaller than the header size")
+	}
+	header = record[:tlsRecordHeaderSize]
+	payload = record[tlsRecordHeaderSize:]
+	if header[0] != tlsApplicationData {
+		return nil, nil, fmt.Errorf("incorrect type in the header")
+	}
+	// Check the legacy record version, which should be 0x03, 0x03.
+	if header[1] != 0x03 || header[2] != 0x03 {
+		return nil, nil, fmt.Errorf("incorrect legacy record version in the header")
+	}
+	return header, payload, nil
+}
+
+// handleAlertMessage handles an alert message.
+func (p *conn) handleAlertMessage() error {
+	if len(p.pendingApplicationData) != tlsAlertSize {
+		return errors.New("invalid alert message size")
+	}
+	alertType := p.pendingApplicationData[1]
+	// Clear the body of the alert message.
+	p.pendingApplicationData = p.pendingApplicationData[:0]
+	if alertType == byte(closeNotify) {
+		return errors.New("received a close notify alert")
+	}
+	// TODO(matthewstevenson88): Add support for more alert types.
+	return fmt.Errorf("received an unrecognized alert type: %v", alertType)
+}
+
+// parseHandshakeHeader parses a handshake message from the handshake buffer.
+// It returns the message type, the message length, the message, the raw message
+// that includes the type and length bytes and a flag indicating whether the
+// handshake message has been fully parsed. i.e. whether the entire handshake
+// message was in the handshake buffer.
+func (p *conn) parseHandshakeMsg() (msgType byte, msgLen uint32, msg []byte, rawMsg []byte, ok bool) {
+	// Handle the case where the 4 byte handshake header is fragmented.
+	if len(p.handshakeBuf) < tlsHandshakePrefixSize {
+		return 0, 0, nil, nil, false
+	}
+	msgType = p.handshakeBuf[0]
+	msgLen = bigEndianInt24(p.handshakeBuf[tlsHandshakeMsgTypeSize : tlsHandshakeMsgTypeSize+tlsHandshakeLengthSize])
+	if msgLen > uint32(len(p.handshakeBuf)-tlsHandshakePrefixSize) {
+		return 0, 0, nil, nil, false
+	}
+	msg = p.handshakeBuf[tlsHandshakePrefixSize : tlsHandshakePrefixSize+msgLen]
+	rawMsg = p.handshakeBuf[:tlsHandshakeMsgTypeSize+tlsHandshakeLengthSize+msgLen]
+	p.handshakeBuf = p.handshakeBuf[tlsHandshakePrefixSize+msgLen:]
+	return msgType, msgLen, msg, rawMsg, true
+}
+
+// handleHandshakeMessage handles a handshake message. Note that the first
+// complete handshake message from the handshake buffer is removed, if it
+// exists.
+func (p *conn) handleHandshakeMessage() error {
+	// Copy the pending application data to the handshake buffer. At this point,
+	// we are guaranteed that the pending application data contains only parts
+	// of a handshake message.
+	p.handshakeBuf = append(p.handshakeBuf, p.pendingApplicationData...)
+	p.pendingApplicationData = p.pendingApplicationData[:0]
+	// Several handshake messages may be coalesced into a single record.
+	// Continue reading them until the handshake buffer is empty.
+	for len(p.handshakeBuf) > 0 {
+		handshakeMsgType, msgLen, msg, rawMsg, ok := p.parseHandshakeMsg()
+		if !ok {
+			// The handshake could not be fully parsed, so read in another
+			// record and try again later.
+			break
+		}
+		switch handshakeMsgType {
+		case tlsHandshakeKeyUpdateType:
+			if msgLen != tlsHandshakeKeyUpdateMsgSize {
+				return errors.New("invalid handshake key update message length")
+			}
+			if len(p.handshakeBuf) != 0 {
+				return errors.New("key update message must be the last message of a handshake record")
+			}
+			if err := p.handleKeyUpdateMsg(msg); err != nil {
+				return err
+			}
+		case tlsHandshakeNewSessionTicketType:
+			// Ignore tickets that are received after a batch of tickets has
+			// been sent to S2A.
+			if p.ticketState == notReceivingTickets {
+				continue
+			}
+			if p.ticketState == ticketsNotYetReceived {
+				p.ticketState = receivingTickets
+			}
+			p.sessionTickets = append(p.sessionTickets, rawMsg)
+			if len(p.sessionTickets) == maxAllowedTickets {
+				p.ticketState = notReceivingTickets
+				grpclog.Infof("Sending session tickets to S2A.")
+				p.ticketSender.sendTicketsToS2A(p.sessionTickets, p.callComplete)
+			}
+		default:
+			return errors.New("unknown handshake message type")
+		}
+	}
+	return nil
+}
+
+func buildKeyUpdateRequest() []byte {
+	b := make([]byte, tlsHandshakePrefixSize+tlsHandshakeKeyUpdateMsgSize)
+	b[0] = tlsHandshakeKeyUpdateType
+	b[1] = 0
+	b[2] = 0
+	b[3] = tlsHandshakeKeyUpdateMsgSize
+	b[4] = byte(updateNotRequested)
+	return b
+}
+
+// handleKeyUpdateMsg handles a key update message.
+func (p *conn) handleKeyUpdateMsg(msg []byte) error {
+	keyUpdateRequest := msg[0]
+	if keyUpdateRequest != byte(updateNotRequested) &&
+		keyUpdateRequest != byte(updateRequested) {
+		return errors.New("invalid handshake key update message")
+	}
+	if err := p.inConn.UpdateKey(); err != nil {
+		return err
+	}
+	// Send a key update message back to the peer if requested.
+	if keyUpdateRequest == byte(updateRequested) {
+		p.writeMutex.Lock()
+		defer p.writeMutex.Unlock()
+		n, err := p.writeTLSRecord(preConstructedKeyUpdateMsg, byte(handshake))
+		if err != nil {
+			return err
+		}
+		if n != tlsHandshakePrefixSize+tlsHandshakeKeyUpdateMsgSize {
+			return errors.New("key update request message wrote less bytes than expected")
+		}
+		if err = p.outConn.UpdateKey(); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// bidEndianInt24 converts the given byte buffer of at least size 3 and
+// outputs the resulting 24 bit integer as a uint32. This is needed because
+// TLS 1.3 requires 3 byte integers, and the binary.BigEndian package does
+// not provide a way to transform a byte buffer into a 3 byte integer.
+func bigEndianInt24(b []byte) uint32 {
+	_ = b[2] // bounds check hint to compiler; see golang.org/issue/14808
+	return uint32(b[2]) | uint32(b[1])<<8 | uint32(b[0])<<16
+}
+
+func min(a, b int) int {
+	if a < b {
+		return a
+	}
+	return b
+}

+ 176 - 0
vendor/github.com/google/s2a-go/internal/record/ticketsender.go

@@ -0,0 +1,176 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package record
+
+import (
+	"context"
+	"fmt"
+	"sync"
+	"time"
+
+	"github.com/google/s2a-go/internal/handshaker/service"
+	commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
+	s2apb "github.com/google/s2a-go/internal/proto/s2a_go_proto"
+	"github.com/google/s2a-go/internal/tokenmanager"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/grpclog"
+)
+
+// sessionTimeout is the timeout for creating a session with the S2A handshaker
+// service.
+const sessionTimeout = time.Second * 5
+
+// s2aTicketSender sends session tickets to the S2A handshaker service.
+type s2aTicketSender interface {
+	// sendTicketsToS2A sends the given session tickets to the S2A handshaker
+	// service.
+	sendTicketsToS2A(sessionTickets [][]byte, callComplete chan bool)
+}
+
+// ticketStream is the stream used to send and receive session information.
+type ticketStream interface {
+	Send(*s2apb.SessionReq) error
+	Recv() (*s2apb.SessionResp, error)
+}
+
+type ticketSender struct {
+	// hsAddr stores the address of the S2A handshaker service.
+	hsAddr string
+	// connectionID is the connection identifier that was created and sent by
+	// S2A at the end of a handshake.
+	connectionID uint64
+	// localIdentity is the local identity that was used by S2A during session
+	// setup and included in the session result.
+	localIdentity *commonpb.Identity
+	// tokenManager manages access tokens for authenticating to S2A.
+	tokenManager tokenmanager.AccessTokenManager
+	// ensureProcessSessionTickets allows users to wait and ensure that all
+	// available session tickets are sent to S2A before a process completes.
+	ensureProcessSessionTickets *sync.WaitGroup
+}
+
+// sendTicketsToS2A sends the given sessionTickets to the S2A handshaker
+// service. This is done asynchronously and writes to the error logs if an error
+// occurs.
+func (t *ticketSender) sendTicketsToS2A(sessionTickets [][]byte, callComplete chan bool) {
+	// Note that the goroutine is in the function rather than at the caller
+	// because the fake ticket sender used for testing must run synchronously
+	// so that the session tickets can be accessed from it after the tests have
+	// been run.
+	if t.ensureProcessSessionTickets != nil {
+		t.ensureProcessSessionTickets.Add(1)
+	}
+	go func() {
+		if err := func() error {
+			defer func() {
+				if t.ensureProcessSessionTickets != nil {
+					t.ensureProcessSessionTickets.Done()
+				}
+			}()
+			hsConn, err := service.Dial(t.hsAddr)
+			if err != nil {
+				return err
+			}
+			client := s2apb.NewS2AServiceClient(hsConn)
+			ctx, cancel := context.WithTimeout(context.Background(), sessionTimeout)
+			defer cancel()
+			session, err := client.SetUpSession(ctx)
+			if err != nil {
+				return err
+			}
+			defer func() {
+				if err := session.CloseSend(); err != nil {
+					grpclog.Error(err)
+				}
+			}()
+			return t.writeTicketsToStream(session, sessionTickets)
+		}(); err != nil {
+			grpclog.Errorf("failed to send resumption tickets to S2A with identity: %v, %v",
+				t.localIdentity, err)
+		}
+		callComplete <- true
+		close(callComplete)
+	}()
+}
+
+// writeTicketsToStream writes the given session tickets to the given stream.
+func (t *ticketSender) writeTicketsToStream(stream ticketStream, sessionTickets [][]byte) error {
+	if err := stream.Send(
+		&s2apb.SessionReq{
+			ReqOneof: &s2apb.SessionReq_ResumptionTicket{
+				ResumptionTicket: &s2apb.ResumptionTicketReq{
+					InBytes:       sessionTickets,
+					ConnectionId:  t.connectionID,
+					LocalIdentity: t.localIdentity,
+				},
+			},
+			AuthMechanisms: t.getAuthMechanisms(),
+		},
+	); err != nil {
+		return err
+	}
+	sessionResp, err := stream.Recv()
+	if err != nil {
+		return err
+	}
+	if sessionResp.GetStatus().GetCode() != uint32(codes.OK) {
+		return fmt.Errorf("s2a session ticket response had error status: %v, %v",
+			sessionResp.GetStatus().GetCode(), sessionResp.GetStatus().GetDetails())
+	}
+	return nil
+}
+
+func (t *ticketSender) getAuthMechanisms() []*s2apb.AuthenticationMechanism {
+	if t.tokenManager == nil {
+		return nil
+	}
+	// First handle the special case when no local identity has been provided
+	// by the application. In this case, an AuthenticationMechanism with no local
+	// identity will be sent.
+	if t.localIdentity == nil {
+		token, err := t.tokenManager.DefaultToken()
+		if err != nil {
+			grpclog.Infof("unable to get token for empty local identity: %v", err)
+			return nil
+		}
+		return []*s2apb.AuthenticationMechanism{
+			{
+				MechanismOneof: &s2apb.AuthenticationMechanism_Token{
+					Token: token,
+				},
+			},
+		}
+	}
+
+	// Next, handle the case where the application (or the S2A) has specified
+	// a local identity.
+	token, err := t.tokenManager.Token(t.localIdentity)
+	if err != nil {
+		grpclog.Infof("unable to get token for local identity %v: %v", t.localIdentity, err)
+		return nil
+	}
+	return []*s2apb.AuthenticationMechanism{
+		{
+			Identity: t.localIdentity,
+			MechanismOneof: &s2apb.AuthenticationMechanism_Token{
+				Token: token,
+			},
+		},
+	}
+}

+ 70 - 0
vendor/github.com/google/s2a-go/internal/tokenmanager/tokenmanager.go

@@ -0,0 +1,70 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package tokenmanager provides tokens for authenticating to S2A.
+package tokenmanager
+
+import (
+	"fmt"
+	"os"
+
+	commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
+)
+
+const (
+	s2aAccessTokenEnvironmentVariable = "S2A_ACCESS_TOKEN"
+)
+
+// AccessTokenManager manages tokens for authenticating to S2A.
+type AccessTokenManager interface {
+	// DefaultToken returns a token that an application with no specified local
+	// identity must use to authenticate to S2A.
+	DefaultToken() (token string, err error)
+	// Token returns a token that an application with local identity equal to
+	// identity must use to authenticate to S2A.
+	Token(identity *commonpb.Identity) (token string, err error)
+}
+
+type singleTokenAccessTokenManager struct {
+	token string
+}
+
+// NewSingleTokenAccessTokenManager returns a new AccessTokenManager instance
+// that will always manage the same token.
+//
+// The token to be managed is read from the s2aAccessTokenEnvironmentVariable
+// environment variable. If this environment variable is not set, then this
+// function returns an error.
+func NewSingleTokenAccessTokenManager() (AccessTokenManager, error) {
+	token, variableExists := os.LookupEnv(s2aAccessTokenEnvironmentVariable)
+	if !variableExists {
+		return nil, fmt.Errorf("%s environment variable is not set", s2aAccessTokenEnvironmentVariable)
+	}
+	return &singleTokenAccessTokenManager{token: token}, nil
+}
+
+// DefaultToken always returns the token managed by the
+// singleTokenAccessTokenManager.
+func (m *singleTokenAccessTokenManager) DefaultToken() (string, error) {
+	return m.token, nil
+}
+
+// Token always returns the token managed by the singleTokenAccessTokenManager.
+func (m *singleTokenAccessTokenManager) Token(*commonpb.Identity) (string, error) {
+	return m.token, nil
+}

+ 1 - 0
vendor/github.com/google/s2a-go/internal/v2/README.md

@@ -0,0 +1 @@
+**This directory has the implementation of the S2Av2's gRPC-Go client libraries**

+ 122 - 0
vendor/github.com/google/s2a-go/internal/v2/certverifier/certverifier.go

@@ -0,0 +1,122 @@
+/*
+ *
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package certverifier offloads verifications to S2Av2.
+package certverifier
+
+import (
+	"crypto/x509"
+	"fmt"
+
+	"github.com/google/s2a-go/stream"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/grpclog"
+
+	s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto"
+)
+
+// VerifyClientCertificateChain builds a SessionReq, sends it to S2Av2 and
+// receives a SessionResp.
+func VerifyClientCertificateChain(verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, s2AStream stream.S2AStream) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
+	return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
+		// Offload verification to S2Av2.
+		if grpclog.V(1) {
+			grpclog.Infof("Sending request to S2Av2 for client peer cert chain validation.")
+		}
+		if err := s2AStream.Send(&s2av2pb.SessionReq{
+			ReqOneof: &s2av2pb.SessionReq_ValidatePeerCertificateChainReq{
+				ValidatePeerCertificateChainReq: &s2av2pb.ValidatePeerCertificateChainReq{
+					Mode: verificationMode,
+					PeerOneof: &s2av2pb.ValidatePeerCertificateChainReq_ClientPeer_{
+						ClientPeer: &s2av2pb.ValidatePeerCertificateChainReq_ClientPeer{
+							CertificateChain: rawCerts,
+						},
+					},
+				},
+			},
+		}); err != nil {
+			grpclog.Infof("Failed to send request to S2Av2 for client peer cert chain validation.")
+			return err
+		}
+
+		// Get the response from S2Av2.
+		resp, err := s2AStream.Recv()
+		if err != nil {
+			grpclog.Infof("Failed to receive client peer cert chain validation response from S2Av2.")
+			return err
+		}
+
+		// Parse the response.
+		if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) {
+			return fmt.Errorf("failed to offload client cert verification to S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details)
+
+		}
+
+		if resp.GetValidatePeerCertificateChainResp().ValidationResult != s2av2pb.ValidatePeerCertificateChainResp_SUCCESS {
+			return fmt.Errorf("client cert verification failed: %v", resp.GetValidatePeerCertificateChainResp().ValidationDetails)
+		}
+
+		return nil
+	}
+}
+
+// VerifyServerCertificateChain builds a SessionReq, sends it to S2Av2 and
+// receives a SessionResp.
+func VerifyServerCertificateChain(hostname string, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, s2AStream stream.S2AStream, serverAuthorizationPolicy []byte) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
+	return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
+		// Offload verification to S2Av2.
+		if grpclog.V(1) {
+			grpclog.Infof("Sending request to S2Av2 for server peer cert chain validation.")
+		}
+		if err := s2AStream.Send(&s2av2pb.SessionReq{
+			ReqOneof: &s2av2pb.SessionReq_ValidatePeerCertificateChainReq{
+				ValidatePeerCertificateChainReq: &s2av2pb.ValidatePeerCertificateChainReq{
+					Mode: verificationMode,
+					PeerOneof: &s2av2pb.ValidatePeerCertificateChainReq_ServerPeer_{
+						ServerPeer: &s2av2pb.ValidatePeerCertificateChainReq_ServerPeer{
+							CertificateChain:                   rawCerts,
+							ServerHostname:                     hostname,
+							SerializedUnrestrictedClientPolicy: serverAuthorizationPolicy,
+						},
+					},
+				},
+			},
+		}); err != nil {
+			grpclog.Infof("Failed to send request to S2Av2 for server peer cert chain validation.")
+			return err
+		}
+
+		// Get the response from S2Av2.
+		resp, err := s2AStream.Recv()
+		if err != nil {
+			grpclog.Infof("Failed to receive server peer cert chain validation response from S2Av2.")
+			return err
+		}
+
+		// Parse the response.
+		if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) {
+			return fmt.Errorf("failed to offload server cert verification to S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details)
+		}
+
+		if resp.GetValidatePeerCertificateChainResp().ValidationResult != s2av2pb.ValidatePeerCertificateChainResp_SUCCESS {
+			return fmt.Errorf("server cert verification failed: %v", resp.GetValidatePeerCertificateChainResp().ValidationDetails)
+		}
+
+		return nil
+	}
+}

BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_intermediate_cert.der


BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_leaf_cert.der


BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_root_cert.der


BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_intermediate_cert.der


BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_leaf_cert.der


BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_root_cert.der


+ 186 - 0
vendor/github.com/google/s2a-go/internal/v2/remotesigner/remotesigner.go

@@ -0,0 +1,186 @@
+/*
+ *
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package remotesigner offloads private key operations to S2Av2.
+package remotesigner
+
+import (
+	"crypto"
+	"crypto/rsa"
+	"crypto/x509"
+	"fmt"
+	"io"
+
+	"github.com/google/s2a-go/stream"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/grpclog"
+
+	s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto"
+)
+
+// remoteSigner implementes the crypto.Signer interface.
+type remoteSigner struct {
+	leafCert  *x509.Certificate
+	s2AStream stream.S2AStream
+}
+
+// New returns an instance of RemoteSigner, an implementation of the
+// crypto.Signer interface.
+func New(leafCert *x509.Certificate, s2AStream stream.S2AStream) crypto.Signer {
+	return &remoteSigner{leafCert, s2AStream}
+}
+
+func (s *remoteSigner) Public() crypto.PublicKey {
+	return s.leafCert.PublicKey
+}
+
+func (s *remoteSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
+	signatureAlgorithm, err := getSignatureAlgorithm(opts, s.leafCert)
+	if err != nil {
+		return nil, err
+	}
+
+	req, err := getSignReq(signatureAlgorithm, digest)
+	if err != nil {
+		return nil, err
+	}
+	if grpclog.V(1) {
+		grpclog.Infof("Sending request to S2Av2 for signing operation.")
+	}
+	if err := s.s2AStream.Send(&s2av2pb.SessionReq{
+		ReqOneof: &s2av2pb.SessionReq_OffloadPrivateKeyOperationReq{
+			OffloadPrivateKeyOperationReq: req,
+		},
+	}); err != nil {
+		grpclog.Infof("Failed to send request to S2Av2 for signing operation.")
+		return nil, err
+	}
+
+	resp, err := s.s2AStream.Recv()
+	if err != nil {
+		grpclog.Infof("Failed to receive signing operation response from S2Av2.")
+		return nil, err
+	}
+
+	if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) {
+		return nil, fmt.Errorf("failed to offload signing with private key to S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details)
+	}
+
+	return resp.GetOffloadPrivateKeyOperationResp().GetOutBytes(), nil
+}
+
+// getCert returns the leafCert field in s.
+func (s *remoteSigner) getCert() *x509.Certificate {
+	return s.leafCert
+}
+
+// getStream returns the s2AStream field in s.
+func (s *remoteSigner) getStream() stream.S2AStream {
+	return s.s2AStream
+}
+
+func getSignReq(signatureAlgorithm s2av2pb.SignatureAlgorithm, digest []byte) (*s2av2pb.OffloadPrivateKeyOperationReq, error) {
+	if (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA256) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256) {
+		return &s2av2pb.OffloadPrivateKeyOperationReq{
+			Operation:          s2av2pb.OffloadPrivateKeyOperationReq_SIGN,
+			SignatureAlgorithm: signatureAlgorithm,
+			InBytes: &s2av2pb.OffloadPrivateKeyOperationReq_Sha256Digest{
+				Sha256Digest: digest,
+			},
+		}, nil
+	} else if (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA384) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384) {
+		return &s2av2pb.OffloadPrivateKeyOperationReq{
+			Operation:          s2av2pb.OffloadPrivateKeyOperationReq_SIGN,
+			SignatureAlgorithm: signatureAlgorithm,
+			InBytes: &s2av2pb.OffloadPrivateKeyOperationReq_Sha384Digest{
+				Sha384Digest: digest,
+			},
+		}, nil
+	} else if (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA512) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ED25519) {
+		return &s2av2pb.OffloadPrivateKeyOperationReq{
+			Operation:          s2av2pb.OffloadPrivateKeyOperationReq_SIGN,
+			SignatureAlgorithm: signatureAlgorithm,
+			InBytes: &s2av2pb.OffloadPrivateKeyOperationReq_Sha512Digest{
+				Sha512Digest: digest,
+			},
+		}, nil
+	} else {
+		return nil, fmt.Errorf("unknown signature algorithm: %v", signatureAlgorithm)
+	}
+}
+
+// getSignatureAlgorithm returns the signature algorithm that S2A must use when
+// performing a signing operation that has been offloaded by an application
+// using the crypto/tls libraries.
+func getSignatureAlgorithm(opts crypto.SignerOpts, leafCert *x509.Certificate) (s2av2pb.SignatureAlgorithm, error) {
+	if opts == nil || leafCert == nil {
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm")
+	}
+	switch leafCert.PublicKeyAlgorithm {
+	case x509.RSA:
+		if rsaPSSOpts, ok := opts.(*rsa.PSSOptions); ok {
+			return rsaPSSAlgorithm(rsaPSSOpts)
+		}
+		return rsaPPKCS1Algorithm(opts)
+	case x509.ECDSA:
+		return ecdsaAlgorithm(opts)
+	case x509.Ed25519:
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ED25519, nil
+	default:
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm: %q", leafCert.PublicKeyAlgorithm)
+	}
+}
+
+func rsaPSSAlgorithm(opts *rsa.PSSOptions) (s2av2pb.SignatureAlgorithm, error) {
+	switch opts.HashFunc() {
+	case crypto.SHA256:
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256, nil
+	case crypto.SHA384:
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384, nil
+	case crypto.SHA512:
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512, nil
+	default:
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm")
+	}
+}
+
+func rsaPPKCS1Algorithm(opts crypto.SignerOpts) (s2av2pb.SignatureAlgorithm, error) {
+	switch opts.HashFunc() {
+	case crypto.SHA256:
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA256, nil
+	case crypto.SHA384:
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA384, nil
+	case crypto.SHA512:
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA512, nil
+	default:
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm")
+	}
+}
+
+func ecdsaAlgorithm(opts crypto.SignerOpts) (s2av2pb.SignatureAlgorithm, error) {
+	switch opts.HashFunc() {
+	case crypto.SHA256:
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256, nil
+	case crypto.SHA384:
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384, nil
+	case crypto.SHA512:
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512, nil
+	default:
+		return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm")
+	}
+}

BIN
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.der


+ 24 - 0
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.pem

@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID8TCCAtmgAwIBAgIUKXNlBRVe6UepjQUijIFPZBd/4qYwDQYJKoZIhvcNAQEL
+BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2
+YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE
+AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN
+MjIwNTMxMjAwMzE1WhcNNDIwNTI2MjAwMzE1WjCBhzELMAkGA1UEBhMCVVMxCzAJ
+BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx
+ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ
+KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAOOFuIucH7XXfohGxKd3uR/ihUA/LdduR9I8kfpUEbq5BOt8xZe5/Yn9
+a1ozEHVW6cOAbHbnwAR8tkSgZ/t42QIA2k77HWU1Jh2xiEIsJivo3imm4/kZWuR0
+OqPh7MhzxpR/hvNwpI5mJsAVBWFMa5KtecFZLnyZtwHylrRN1QXzuLrOxuKFufK3
+RKbTABScn5RbZL976H/jgfSeXrbt242NrIoBnVe6fRbekbq2DQ6zFArbQMUgHjHK
+P0UqBgdr1QmHfi9KytFyx9BTP3gXWnWIu+bY7/v7qKJMHFwGETo+dCLWYevJL316
+HnLfhApDMfP8U+Yv/y1N/YvgaSOSlEcCAwEAAaNTMFEwHQYDVR0OBBYEFKhAU4nu
+0h/lrnggbIGvx4ej0WklMB8GA1UdIwQYMBaAFKhAU4nu0h/lrnggbIGvx4ej0Wkl
+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAE/6NghzQ5fu6yR6
+EHKbj/YMrFdT7aGn5n2sAf7wJ33LIhiFHkpWBsVlm7rDtZtwhe891ZK/P60anlg9
+/P0Ua53tSRVRmCvTnEbXWOVMN4is6MsR7BlmzUxl4AtIn7jbeifEwRL7B4xDYmdA
+QrQnsqoz45dLgS5xK4WDqXATP09Q91xQDuhud/b+A4jrvgwFASmL7rMIZbp4f1JQ
+nlnl/9VoTBQBvJiWkDUtQDMpRLtauddEkv4AGz75p5IspXWD6cOemuh2iQec11xD
+X20rs2WZbAcAiUa3nmy8OKYw435vmpj8gp39WYbX/Yx9TymrFFbVY92wYn+quTco
+pKklVz0=
+-----END CERTIFICATE-----

+ 27 - 0
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_key.pem

@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEA44W4i5wftdd+iEbEp3e5H+KFQD8t125H0jyR+lQRurkE63zF
+l7n9if1rWjMQdVbpw4BsdufABHy2RKBn+3jZAgDaTvsdZTUmHbGIQiwmK+jeKabj
++Rla5HQ6o+HsyHPGlH+G83CkjmYmwBUFYUxrkq15wVkufJm3AfKWtE3VBfO4us7G
+4oW58rdEptMAFJyflFtkv3vof+OB9J5etu3bjY2sigGdV7p9Ft6RurYNDrMUCttA
+xSAeMco/RSoGB2vVCYd+L0rK0XLH0FM/eBdadYi75tjv+/uookwcXAYROj50ItZh
+68kvfXoect+ECkMx8/xT5i//LU39i+BpI5KURwIDAQABAoIBABgyjo/6iLzUMFbZ
+/+w3pW6orrdIgN2akvTfED9pVYFgUA+jc3hRhY95bkNnjuaL2cy7Cc4Tk65mfRQL
+Y0OxdJLr+EvSFSxAXM9npDA1ddHRsF8JqtFBSxNk8R+g1Yf0GDiO35Fgd3/ViWWA
+VtQkRoSRApP3oiQKTRZd8H04keFR+PvmDk/Lq11l3Kc24A1PevKIPX1oI990ggw9
+9i4uSV+cnuMxmcI9xxJtgwdDFdjr39l2arLOHr4s6LGoV2IOdXHNlv5xRqWUZ0FH
+MDHowkLgwDrdSTnNeaVNkce14Gqx+bd4hNaLCdKXMpedBTEmrut3f3hdV1kKjaKt
+aqRYr8ECgYEA/YDGZY2jvFoHHBywlqmEMFrrCvQGH51m5R1Ntpkzr+Rh3YCmrpvq
+xgwJXING0PUw3dz+xrH5lJICrfNE5Kt3fPu1rAEy+13mYsNowghtUq2Rtu0Hsjjx
+2E3Bf8vEB6RNBMmGkUpTTIAroGF5tpJoRvfnWax+k4pFdrKYFtyZdNcCgYEA5cNv
+EPltvOobjTXlUmtVP3n27KZN2aXexTcagLzRxE9CV4cYySENl3KuOMmccaZpIl6z
+aHk6BT4X+M0LqElNUczrInfVqI+SGAFLGy7W6CJaqSr6cpyFUP/fosKpm6wKGgLq
+udHfpvz5rckhKd8kJxFLvhGOK9yN5qpzih0gfhECgYAJfwRvk3G5wYmYpP58dlcs
+VIuPenqsPoI3PPTHTU/hW+XKnWIhElgmGRdUrto9Q6IT/Y5RtSMLTLjq+Tzwb/fm
+56rziYv2XJsfwgAvnI8z1Kqrto9ePsHYf3krJ1/thVsZPc9bq/QY3ohD1sLvcuaT
+GgBBnLOVJU3a12/ZE2RwOwKBgF0csWMAoj8/5IB6if+3ral2xOGsl7oPZVMo/J2V
+Z7EVqb4M6rd/pKFugTpUQgkwtkSOekhpcGD1hAN5HTNK2YG/+L5UMAsKe9sskwJm
+HgOfAHy0BSDzW3ey6i9skg2bT9Cww+0gJ3Hl7U1HSCBO5LjMYpSZSrNtwzfqdb5Q
+BX3xAoGARZdR28Ej3+/+0+fz47Yu2h4z0EI/EbrudLOWY936jIeAVwHckI3+BuqH
+qR4poj1gfbnMxNuI9UzIXzjEmGewx9kDZ7IYnvloZKqoVQODO5GlKF2ja6IcMNlh
+GCNdD6PSAS6HcmalmWo9sj+1YMkrl+GJikKZqVBHrHNwMGAG67w=
+-----END RSA PRIVATE KEY-----

BIN
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.der


+ 24 - 0
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.pem

@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID8TCCAtmgAwIBAgIUKCoDuLtiZXvhsBY2RoDm0ugizJ8wDQYJKoZIhvcNAQEL
+BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2
+YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE
+AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN
+MjIwNTMxMjAwODI1WhcNNDIwNTI2MjAwODI1WjCBhzELMAkGA1UEBhMCVVMxCzAJ
+BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx
+ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ
+KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAKK1++PXQ+M3hjYH/v0K4UEYl5ljzpNM1i52eQM+gFooojT87PDSaphT
+fs0PXy/PTAjHBEvPhWpOpmQXfJNYzjwcCvg66hbqkv++/VTZiFLAsHagzkEz+FRJ
+qT5Eq7G5FLyw1izX1uxyPN7tAEWEEg7eqsiaXD3Cq8+TYN9cjirPeF7RZF8yFCYE
+xqvbo+Yc6RL6xw19iXVTfctRgQe581KQuIY5/LXo3dWDEilFdsADAe8XAEcO64es
+Ow0g1UvXLnpXSE151kXBFb3sKH/ZjCecDYMCIMEb4sWLSblkSxJ5sNSmXIG4wtr2
+Qnii7CXZgnVYraQE/Jyh+NMQANuoSdMCAwEAAaNTMFEwHQYDVR0OBBYEFAyQQQuM
+ab+YUQqjK8dVVOoHVFmXMB8GA1UdIwQYMBaAFAyQQQuMab+YUQqjK8dVVOoHVFmX
+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADj0vQ6ykWhicoqR
+e6VZMwlEJV7/DSvWWKBd9MUjfKye0A4565ya5lmnzP3DiD3nqGe3miqmLsXKDs+X
+POqlPXTWIamP7D4MJ32XtSLwZB4ru+I+Ao/P/VngPepoRPQoBnzHe7jww0rokqxl
+AZERjlbTUwUAy/BPWPSzSJZ2j0tcs6ZLDNyYzpK4ao8R9/1VmQ92Tcp3feJs1QTg
+odRQc3om/AkWOwsll+oyX0UbJeHkFHiLanUPXbdh+/BkSvZJ8ynL+feSDdaurPe+
+PSfnqLtQft9/neecGRdEaQzzzSFVQUVQzTdK1Q7hA7b55b2HvIa3ktDiks+sJsYN
+Dhm6uZM=
+-----END CERTIFICATE-----

+ 27 - 0
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_key.pem

@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAorX749dD4zeGNgf+/QrhQRiXmWPOk0zWLnZ5Az6AWiiiNPzs
+8NJqmFN+zQ9fL89MCMcES8+Fak6mZBd8k1jOPBwK+DrqFuqS/779VNmIUsCwdqDO
+QTP4VEmpPkSrsbkUvLDWLNfW7HI83u0ARYQSDt6qyJpcPcKrz5Ng31yOKs94XtFk
+XzIUJgTGq9uj5hzpEvrHDX2JdVN9y1GBB7nzUpC4hjn8tejd1YMSKUV2wAMB7xcA
+Rw7rh6w7DSDVS9cueldITXnWRcEVvewof9mMJ5wNgwIgwRvixYtJuWRLEnmw1KZc
+gbjC2vZCeKLsJdmCdVitpAT8nKH40xAA26hJ0wIDAQABAoIBACaNR+lsD8G+XiZf
+LqN1+HkcAo9tfnyYMAdCOtnx7SdviT9Uzi8hK/B7mAeuJLeHPlS2EuaDfPD7QaFl
+jza6S+MiIdc+3kgfvESsVAnOoOY6kZUJ9NSuI6CU82y1iJjLaYZrv9NQMLRFPPb0
+4KOX709mosB1EnXvshW0rbc+jtDFhrm1SxMt+k9TuzmMxjbOeW4LOLXPgU8X1T3Q
+Xy0hMZZtcgBs9wFIo8yCtmOixax9pnFE8rRltgDxTodn9LLdz1FieyntNgDksZ0P
+nt4kV7Mqly7ELaea+Foaj244mKsesic2e3GhAlMRLun/VSunSf7mOCxfpITB8dp1
+drDhOYECgYEA19151dVxRcviuovN6Dar+QszMTnU8pDJ8BjLFjXjP/hNBBwMTHDE
+duMuWk2qnwZqMooI/shxrF/ufmTgS0CFrh2+ANBZu27vWConJNXcyNtdigI4wt50
+L0Y2qcZn2mg67qFXHwoR3QNwrwnPwEjRXA09at9CSRZzcwDQ0ETXhYsCgYEAwPaG
+06QdK8Zyly7TTzZJwxzv9uGiqzodmGtX6NEKjgij2JaCxHpukqZBJoqa0jKeK1cm
+eNVkOvT5ff9TMzarSHQLr3pZen2/oVLb5gaFkbcJt/klv9Fd+ZRilHY3i6QwS6pD
+uMiPOWS4DrLHDRVoVlAZTDjT1RVwwTs+P2NhJdkCgYEAsriXysbxBYyMp05gqEW7
+lHIFbFgpSrs9th+Q5U6wW6JEgYaHWDJ1NslY80MiZI93FWjbkbZ7BvBWESeL3EIL
+a+EMErht0pVCbIhZ6FF4foPAqia0wAJVx14mm+G80kNBp5jE/NnleEsE3KcO7nBb
+hg8gLn+x7bk81JZ0TDrzBYkCgYEAuQKluv47SeF3tSScTfKLPpvcKCWmxe1uutkQ
+7JShPhVioyOMNb39jnYBOWbjkm4d4QgqRuiytSR0oi3QI+Ziy5EYMyNn713qAk9j
+r2TJZDDPDKnBW+zt4YI4EohWMXk3JRUW4XDKggjjwJQA7bZ812TtHHvP/xoThfG7
+eSNb3eECgYBw6ssgCtMrdvQiEmjKVX/9yI38mvC2kSGyzbrQnGUfgqRGomRpeZuD
+B5E3kysA4td5pT5lvcLgSW0TbOz+YbiriXjwOihPIelCvc9gE2eOUI71/byUWPFz
+7u5F/xQ4NaGr5suLF+lBC6h7pSbM4El9lIHQAQadpuEdzHqrw+hs3g==
+-----END RSA PRIVATE KEY-----

+ 354 - 0
vendor/github.com/google/s2a-go/internal/v2/s2av2.go

@@ -0,0 +1,354 @@
+/*
+ *
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package v2 provides the S2Av2 transport credentials used by a gRPC
+// application.
+package v2
+
+import (
+	"context"
+	"crypto/tls"
+	"errors"
+	"net"
+	"os"
+	"time"
+
+	"github.com/golang/protobuf/proto"
+	"github.com/google/s2a-go/fallback"
+	"github.com/google/s2a-go/internal/handshaker/service"
+	"github.com/google/s2a-go/internal/tokenmanager"
+	"github.com/google/s2a-go/internal/v2/tlsconfigstore"
+	"github.com/google/s2a-go/stream"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials"
+	"google.golang.org/grpc/grpclog"
+
+	commonpbv1 "github.com/google/s2a-go/internal/proto/common_go_proto"
+	s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto"
+)
+
+const (
+	s2aSecurityProtocol = "tls"
+	defaultS2ATimeout   = 3 * time.Second
+)
+
+// An environment variable, which sets the timeout enforced on the connection to the S2A service for handshake.
+const s2aTimeoutEnv = "S2A_TIMEOUT"
+
+type s2av2TransportCreds struct {
+	info         *credentials.ProtocolInfo
+	isClient     bool
+	serverName   string
+	s2av2Address string
+	tokenManager *tokenmanager.AccessTokenManager
+	// localIdentity should only be used by the client.
+	localIdentity *commonpbv1.Identity
+	// localIdentities should only be used by the server.
+	localIdentities           []*commonpbv1.Identity
+	verificationMode          s2av2pb.ValidatePeerCertificateChainReq_VerificationMode
+	fallbackClientHandshake   fallback.ClientHandshake
+	getS2AStream              func(ctx context.Context, s2av2Address string) (stream.S2AStream, error)
+	serverAuthorizationPolicy []byte
+}
+
+// NewClientCreds returns a client-side transport credentials object that uses
+// the S2Av2 to establish a secure connection with a server.
+func NewClientCreds(s2av2Address string, localIdentity *commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, fallbackClientHandshakeFunc fallback.ClientHandshake, getS2AStream func(ctx context.Context, s2av2Address string) (stream.S2AStream, error), serverAuthorizationPolicy []byte) (credentials.TransportCredentials, error) {
+	// Create an AccessTokenManager instance to use to authenticate to S2Av2.
+	accessTokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager()
+
+	creds := &s2av2TransportCreds{
+		info: &credentials.ProtocolInfo{
+			SecurityProtocol: s2aSecurityProtocol,
+		},
+		isClient:                  true,
+		serverName:                "",
+		s2av2Address:              s2av2Address,
+		localIdentity:             localIdentity,
+		verificationMode:          verificationMode,
+		fallbackClientHandshake:   fallbackClientHandshakeFunc,
+		getS2AStream:              getS2AStream,
+		serverAuthorizationPolicy: serverAuthorizationPolicy,
+	}
+	if err != nil {
+		creds.tokenManager = nil
+	} else {
+		creds.tokenManager = &accessTokenManager
+	}
+	if grpclog.V(1) {
+		grpclog.Info("Created client S2Av2 transport credentials.")
+	}
+	return creds, nil
+}
+
+// NewServerCreds returns a server-side transport credentials object that uses
+// the S2Av2 to establish a secure connection with a client.
+func NewServerCreds(s2av2Address string, localIdentities []*commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, getS2AStream func(ctx context.Context, s2av2Address string) (stream.S2AStream, error)) (credentials.TransportCredentials, error) {
+	// Create an AccessTokenManager instance to use to authenticate to S2Av2.
+	accessTokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager()
+	creds := &s2av2TransportCreds{
+		info: &credentials.ProtocolInfo{
+			SecurityProtocol: s2aSecurityProtocol,
+		},
+		isClient:         false,
+		s2av2Address:     s2av2Address,
+		localIdentities:  localIdentities,
+		verificationMode: verificationMode,
+		getS2AStream:     getS2AStream,
+	}
+	if err != nil {
+		creds.tokenManager = nil
+	} else {
+		creds.tokenManager = &accessTokenManager
+	}
+	if grpclog.V(1) {
+		grpclog.Info("Created server S2Av2 transport credentials.")
+	}
+	return creds, nil
+}
+
+// ClientHandshake performs a client-side mTLS handshake using the S2Av2.
+func (c *s2av2TransportCreds) ClientHandshake(ctx context.Context, serverAuthority string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
+	if !c.isClient {
+		return nil, nil, errors.New("client handshake called using server transport credentials")
+	}
+	// Remove the port from serverAuthority.
+	serverName := removeServerNamePort(serverAuthority)
+	timeoutCtx, cancel := context.WithTimeout(ctx, GetS2ATimeout())
+	defer cancel()
+	s2AStream, err := createStream(timeoutCtx, c.s2av2Address, c.getS2AStream)
+	if err != nil {
+		grpclog.Infof("Failed to connect to S2Av2: %v", err)
+		if c.fallbackClientHandshake != nil {
+			return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err)
+		}
+		return nil, nil, err
+	}
+	defer s2AStream.CloseSend()
+	if grpclog.V(1) {
+		grpclog.Infof("Connected to S2Av2.")
+	}
+	var config *tls.Config
+
+	var tokenManager tokenmanager.AccessTokenManager
+	if c.tokenManager == nil {
+		tokenManager = nil
+	} else {
+		tokenManager = *c.tokenManager
+	}
+
+	if c.serverName == "" {
+		config, err = tlsconfigstore.GetTLSConfigurationForClient(serverName, s2AStream, tokenManager, c.localIdentity, c.verificationMode, c.serverAuthorizationPolicy)
+		if err != nil {
+			grpclog.Info("Failed to get client TLS config from S2Av2: %v", err)
+			if c.fallbackClientHandshake != nil {
+				return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err)
+			}
+			return nil, nil, err
+		}
+	} else {
+		config, err = tlsconfigstore.GetTLSConfigurationForClient(c.serverName, s2AStream, tokenManager, c.localIdentity, c.verificationMode, c.serverAuthorizationPolicy)
+		if err != nil {
+			grpclog.Info("Failed to get client TLS config from S2Av2: %v", err)
+			if c.fallbackClientHandshake != nil {
+				return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err)
+			}
+			return nil, nil, err
+		}
+	}
+	if grpclog.V(1) {
+		grpclog.Infof("Got client TLS config from S2Av2.")
+	}
+	creds := credentials.NewTLS(config)
+
+	conn, authInfo, err := creds.ClientHandshake(ctx, serverName, rawConn)
+	if err != nil {
+		grpclog.Infof("Failed to do client handshake using S2Av2: %v", err)
+		if c.fallbackClientHandshake != nil {
+			return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err)
+		}
+		return nil, nil, err
+	}
+	grpclog.Infof("Successfully done client handshake using S2Av2 to: %s", serverName)
+
+	return conn, authInfo, err
+}
+
+// ServerHandshake performs a server-side mTLS handshake using the S2Av2.
+func (c *s2av2TransportCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
+	if c.isClient {
+		return nil, nil, errors.New("server handshake called using client transport credentials")
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), GetS2ATimeout())
+	defer cancel()
+	s2AStream, err := createStream(ctx, c.s2av2Address, c.getS2AStream)
+	if err != nil {
+		grpclog.Infof("Failed to connect to S2Av2: %v", err)
+		return nil, nil, err
+	}
+	defer s2AStream.CloseSend()
+	if grpclog.V(1) {
+		grpclog.Infof("Connected to S2Av2.")
+	}
+
+	var tokenManager tokenmanager.AccessTokenManager
+	if c.tokenManager == nil {
+		tokenManager = nil
+	} else {
+		tokenManager = *c.tokenManager
+	}
+
+	config, err := tlsconfigstore.GetTLSConfigurationForServer(s2AStream, tokenManager, c.localIdentities, c.verificationMode)
+	if err != nil {
+		grpclog.Infof("Failed to get server TLS config from S2Av2: %v", err)
+		return nil, nil, err
+	}
+	if grpclog.V(1) {
+		grpclog.Infof("Got server TLS config from S2Av2.")
+	}
+	creds := credentials.NewTLS(config)
+	return creds.ServerHandshake(rawConn)
+}
+
+// Info returns protocol info of s2av2TransportCreds.
+func (c *s2av2TransportCreds) Info() credentials.ProtocolInfo {
+	return *c.info
+}
+
+// Clone makes a deep copy of s2av2TransportCreds.
+func (c *s2av2TransportCreds) Clone() credentials.TransportCredentials {
+	info := *c.info
+	serverName := c.serverName
+	fallbackClientHandshake := c.fallbackClientHandshake
+
+	s2av2Address := c.s2av2Address
+	var tokenManager tokenmanager.AccessTokenManager
+	if c.tokenManager == nil {
+		tokenManager = nil
+	} else {
+		tokenManager = *c.tokenManager
+	}
+	verificationMode := c.verificationMode
+	var localIdentity *commonpbv1.Identity
+	if c.localIdentity != nil {
+		localIdentity = proto.Clone(c.localIdentity).(*commonpbv1.Identity)
+	}
+	var localIdentities []*commonpbv1.Identity
+	if c.localIdentities != nil {
+		localIdentities = make([]*commonpbv1.Identity, len(c.localIdentities))
+		for i, localIdentity := range c.localIdentities {
+			localIdentities[i] = proto.Clone(localIdentity).(*commonpbv1.Identity)
+		}
+	}
+	creds := &s2av2TransportCreds{
+		info:                    &info,
+		isClient:                c.isClient,
+		serverName:              serverName,
+		fallbackClientHandshake: fallbackClientHandshake,
+		s2av2Address:            s2av2Address,
+		localIdentity:           localIdentity,
+		localIdentities:         localIdentities,
+		verificationMode:        verificationMode,
+	}
+	if c.tokenManager == nil {
+		creds.tokenManager = nil
+	} else {
+		creds.tokenManager = &tokenManager
+	}
+	return creds
+}
+
+// NewClientTLSConfig returns a tls.Config instance that uses S2Av2 to establish a TLS connection as
+// a client. The tls.Config MUST only be used to establish a single TLS connection.
+func NewClientTLSConfig(
+	ctx context.Context,
+	s2av2Address string,
+	tokenManager tokenmanager.AccessTokenManager,
+	verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode,
+	serverName string,
+	serverAuthorizationPolicy []byte) (*tls.Config, error) {
+	s2AStream, err := createStream(ctx, s2av2Address, nil)
+	if err != nil {
+		grpclog.Infof("Failed to connect to S2Av2: %v", err)
+		return nil, err
+	}
+
+	return tlsconfigstore.GetTLSConfigurationForClient(removeServerNamePort(serverName), s2AStream, tokenManager, nil, verificationMode, serverAuthorizationPolicy)
+}
+
+// OverrideServerName sets the ServerName in the s2av2TransportCreds protocol
+// info. The ServerName MUST be a hostname.
+func (c *s2av2TransportCreds) OverrideServerName(serverNameOverride string) error {
+	serverName := removeServerNamePort(serverNameOverride)
+	c.info.ServerName = serverName
+	c.serverName = serverName
+	return nil
+}
+
+// Remove the trailing port from server name.
+func removeServerNamePort(serverName string) string {
+	name, _, err := net.SplitHostPort(serverName)
+	if err != nil {
+		name = serverName
+	}
+	return name
+}
+
+type s2AGrpcStream struct {
+	stream s2av2pb.S2AService_SetUpSessionClient
+}
+
+func (x s2AGrpcStream) Send(m *s2av2pb.SessionReq) error {
+	return x.stream.Send(m)
+}
+
+func (x s2AGrpcStream) Recv() (*s2av2pb.SessionResp, error) {
+	return x.stream.Recv()
+}
+
+func (x s2AGrpcStream) CloseSend() error {
+	return x.stream.CloseSend()
+}
+
+func createStream(ctx context.Context, s2av2Address string, getS2AStream func(ctx context.Context, s2av2Address string) (stream.S2AStream, error)) (stream.S2AStream, error) {
+	if getS2AStream != nil {
+		return getS2AStream(ctx, s2av2Address)
+	}
+	// TODO(rmehta19): Consider whether to close the connection to S2Av2.
+	conn, err := service.Dial(s2av2Address)
+	if err != nil {
+		return nil, err
+	}
+	client := s2av2pb.NewS2AServiceClient(conn)
+	gRPCStream, err := client.SetUpSession(ctx, []grpc.CallOption{}...)
+	if err != nil {
+		return nil, err
+	}
+	return &s2AGrpcStream{
+		stream: gRPCStream,
+	}, nil
+}
+
+// GetS2ATimeout returns the timeout enforced on the connection to the S2A service for handshake.
+func GetS2ATimeout() time.Duration {
+	timeout, err := time.ParseDuration(os.Getenv(s2aTimeoutEnv))
+	if err != nil {
+		return defaultS2ATimeout
+	}
+	return timeout
+}

+ 24 - 0
vendor/github.com/google/s2a-go/internal/v2/testdata/client_cert.pem

@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID8TCCAtmgAwIBAgIUKXNlBRVe6UepjQUijIFPZBd/4qYwDQYJKoZIhvcNAQEL
+BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2
+YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE
+AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN
+MjIwNTMxMjAwMzE1WhcNNDIwNTI2MjAwMzE1WjCBhzELMAkGA1UEBhMCVVMxCzAJ
+BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx
+ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ
+KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAOOFuIucH7XXfohGxKd3uR/ihUA/LdduR9I8kfpUEbq5BOt8xZe5/Yn9
+a1ozEHVW6cOAbHbnwAR8tkSgZ/t42QIA2k77HWU1Jh2xiEIsJivo3imm4/kZWuR0
+OqPh7MhzxpR/hvNwpI5mJsAVBWFMa5KtecFZLnyZtwHylrRN1QXzuLrOxuKFufK3
+RKbTABScn5RbZL976H/jgfSeXrbt242NrIoBnVe6fRbekbq2DQ6zFArbQMUgHjHK
+P0UqBgdr1QmHfi9KytFyx9BTP3gXWnWIu+bY7/v7qKJMHFwGETo+dCLWYevJL316
+HnLfhApDMfP8U+Yv/y1N/YvgaSOSlEcCAwEAAaNTMFEwHQYDVR0OBBYEFKhAU4nu
+0h/lrnggbIGvx4ej0WklMB8GA1UdIwQYMBaAFKhAU4nu0h/lrnggbIGvx4ej0Wkl
+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAE/6NghzQ5fu6yR6
+EHKbj/YMrFdT7aGn5n2sAf7wJ33LIhiFHkpWBsVlm7rDtZtwhe891ZK/P60anlg9
+/P0Ua53tSRVRmCvTnEbXWOVMN4is6MsR7BlmzUxl4AtIn7jbeifEwRL7B4xDYmdA
+QrQnsqoz45dLgS5xK4WDqXATP09Q91xQDuhud/b+A4jrvgwFASmL7rMIZbp4f1JQ
+nlnl/9VoTBQBvJiWkDUtQDMpRLtauddEkv4AGz75p5IspXWD6cOemuh2iQec11xD
+X20rs2WZbAcAiUa3nmy8OKYw435vmpj8gp39WYbX/Yx9TymrFFbVY92wYn+quTco
+pKklVz0=
+-----END CERTIFICATE-----

+ 27 - 0
vendor/github.com/google/s2a-go/internal/v2/testdata/client_key.pem

@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEA44W4i5wftdd+iEbEp3e5H+KFQD8t125H0jyR+lQRurkE63zF
+l7n9if1rWjMQdVbpw4BsdufABHy2RKBn+3jZAgDaTvsdZTUmHbGIQiwmK+jeKabj
++Rla5HQ6o+HsyHPGlH+G83CkjmYmwBUFYUxrkq15wVkufJm3AfKWtE3VBfO4us7G
+4oW58rdEptMAFJyflFtkv3vof+OB9J5etu3bjY2sigGdV7p9Ft6RurYNDrMUCttA
+xSAeMco/RSoGB2vVCYd+L0rK0XLH0FM/eBdadYi75tjv+/uookwcXAYROj50ItZh
+68kvfXoect+ECkMx8/xT5i//LU39i+BpI5KURwIDAQABAoIBABgyjo/6iLzUMFbZ
+/+w3pW6orrdIgN2akvTfED9pVYFgUA+jc3hRhY95bkNnjuaL2cy7Cc4Tk65mfRQL
+Y0OxdJLr+EvSFSxAXM9npDA1ddHRsF8JqtFBSxNk8R+g1Yf0GDiO35Fgd3/ViWWA
+VtQkRoSRApP3oiQKTRZd8H04keFR+PvmDk/Lq11l3Kc24A1PevKIPX1oI990ggw9
+9i4uSV+cnuMxmcI9xxJtgwdDFdjr39l2arLOHr4s6LGoV2IOdXHNlv5xRqWUZ0FH
+MDHowkLgwDrdSTnNeaVNkce14Gqx+bd4hNaLCdKXMpedBTEmrut3f3hdV1kKjaKt
+aqRYr8ECgYEA/YDGZY2jvFoHHBywlqmEMFrrCvQGH51m5R1Ntpkzr+Rh3YCmrpvq
+xgwJXING0PUw3dz+xrH5lJICrfNE5Kt3fPu1rAEy+13mYsNowghtUq2Rtu0Hsjjx
+2E3Bf8vEB6RNBMmGkUpTTIAroGF5tpJoRvfnWax+k4pFdrKYFtyZdNcCgYEA5cNv
+EPltvOobjTXlUmtVP3n27KZN2aXexTcagLzRxE9CV4cYySENl3KuOMmccaZpIl6z
+aHk6BT4X+M0LqElNUczrInfVqI+SGAFLGy7W6CJaqSr6cpyFUP/fosKpm6wKGgLq
+udHfpvz5rckhKd8kJxFLvhGOK9yN5qpzih0gfhECgYAJfwRvk3G5wYmYpP58dlcs
+VIuPenqsPoI3PPTHTU/hW+XKnWIhElgmGRdUrto9Q6IT/Y5RtSMLTLjq+Tzwb/fm
+56rziYv2XJsfwgAvnI8z1Kqrto9ePsHYf3krJ1/thVsZPc9bq/QY3ohD1sLvcuaT
+GgBBnLOVJU3a12/ZE2RwOwKBgF0csWMAoj8/5IB6if+3ral2xOGsl7oPZVMo/J2V
+Z7EVqb4M6rd/pKFugTpUQgkwtkSOekhpcGD1hAN5HTNK2YG/+L5UMAsKe9sskwJm
+HgOfAHy0BSDzW3ey6i9skg2bT9Cww+0gJ3Hl7U1HSCBO5LjMYpSZSrNtwzfqdb5Q
+BX3xAoGARZdR28Ej3+/+0+fz47Yu2h4z0EI/EbrudLOWY936jIeAVwHckI3+BuqH
+qR4poj1gfbnMxNuI9UzIXzjEmGewx9kDZ7IYnvloZKqoVQODO5GlKF2ja6IcMNlh
+GCNdD6PSAS6HcmalmWo9sj+1YMkrl+GJikKZqVBHrHNwMGAG67w=
+-----END RSA PRIVATE KEY-----

+ 24 - 0
vendor/github.com/google/s2a-go/internal/v2/testdata/server_cert.pem

@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID8TCCAtmgAwIBAgIUKCoDuLtiZXvhsBY2RoDm0ugizJ8wDQYJKoZIhvcNAQEL
+BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2
+YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE
+AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN
+MjIwNTMxMjAwODI1WhcNNDIwNTI2MjAwODI1WjCBhzELMAkGA1UEBhMCVVMxCzAJ
+BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx
+ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ
+KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAKK1++PXQ+M3hjYH/v0K4UEYl5ljzpNM1i52eQM+gFooojT87PDSaphT
+fs0PXy/PTAjHBEvPhWpOpmQXfJNYzjwcCvg66hbqkv++/VTZiFLAsHagzkEz+FRJ
+qT5Eq7G5FLyw1izX1uxyPN7tAEWEEg7eqsiaXD3Cq8+TYN9cjirPeF7RZF8yFCYE
+xqvbo+Yc6RL6xw19iXVTfctRgQe581KQuIY5/LXo3dWDEilFdsADAe8XAEcO64es
+Ow0g1UvXLnpXSE151kXBFb3sKH/ZjCecDYMCIMEb4sWLSblkSxJ5sNSmXIG4wtr2
+Qnii7CXZgnVYraQE/Jyh+NMQANuoSdMCAwEAAaNTMFEwHQYDVR0OBBYEFAyQQQuM
+ab+YUQqjK8dVVOoHVFmXMB8GA1UdIwQYMBaAFAyQQQuMab+YUQqjK8dVVOoHVFmX
+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADj0vQ6ykWhicoqR
+e6VZMwlEJV7/DSvWWKBd9MUjfKye0A4565ya5lmnzP3DiD3nqGe3miqmLsXKDs+X
+POqlPXTWIamP7D4MJ32XtSLwZB4ru+I+Ao/P/VngPepoRPQoBnzHe7jww0rokqxl
+AZERjlbTUwUAy/BPWPSzSJZ2j0tcs6ZLDNyYzpK4ao8R9/1VmQ92Tcp3feJs1QTg
+odRQc3om/AkWOwsll+oyX0UbJeHkFHiLanUPXbdh+/BkSvZJ8ynL+feSDdaurPe+
+PSfnqLtQft9/neecGRdEaQzzzSFVQUVQzTdK1Q7hA7b55b2HvIa3ktDiks+sJsYN
+Dhm6uZM=
+-----END CERTIFICATE-----

+ 27 - 0
vendor/github.com/google/s2a-go/internal/v2/testdata/server_key.pem

@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAorX749dD4zeGNgf+/QrhQRiXmWPOk0zWLnZ5Az6AWiiiNPzs
+8NJqmFN+zQ9fL89MCMcES8+Fak6mZBd8k1jOPBwK+DrqFuqS/779VNmIUsCwdqDO
+QTP4VEmpPkSrsbkUvLDWLNfW7HI83u0ARYQSDt6qyJpcPcKrz5Ng31yOKs94XtFk
+XzIUJgTGq9uj5hzpEvrHDX2JdVN9y1GBB7nzUpC4hjn8tejd1YMSKUV2wAMB7xcA
+Rw7rh6w7DSDVS9cueldITXnWRcEVvewof9mMJ5wNgwIgwRvixYtJuWRLEnmw1KZc
+gbjC2vZCeKLsJdmCdVitpAT8nKH40xAA26hJ0wIDAQABAoIBACaNR+lsD8G+XiZf
+LqN1+HkcAo9tfnyYMAdCOtnx7SdviT9Uzi8hK/B7mAeuJLeHPlS2EuaDfPD7QaFl
+jza6S+MiIdc+3kgfvESsVAnOoOY6kZUJ9NSuI6CU82y1iJjLaYZrv9NQMLRFPPb0
+4KOX709mosB1EnXvshW0rbc+jtDFhrm1SxMt+k9TuzmMxjbOeW4LOLXPgU8X1T3Q
+Xy0hMZZtcgBs9wFIo8yCtmOixax9pnFE8rRltgDxTodn9LLdz1FieyntNgDksZ0P
+nt4kV7Mqly7ELaea+Foaj244mKsesic2e3GhAlMRLun/VSunSf7mOCxfpITB8dp1
+drDhOYECgYEA19151dVxRcviuovN6Dar+QszMTnU8pDJ8BjLFjXjP/hNBBwMTHDE
+duMuWk2qnwZqMooI/shxrF/ufmTgS0CFrh2+ANBZu27vWConJNXcyNtdigI4wt50
+L0Y2qcZn2mg67qFXHwoR3QNwrwnPwEjRXA09at9CSRZzcwDQ0ETXhYsCgYEAwPaG
+06QdK8Zyly7TTzZJwxzv9uGiqzodmGtX6NEKjgij2JaCxHpukqZBJoqa0jKeK1cm
+eNVkOvT5ff9TMzarSHQLr3pZen2/oVLb5gaFkbcJt/klv9Fd+ZRilHY3i6QwS6pD
+uMiPOWS4DrLHDRVoVlAZTDjT1RVwwTs+P2NhJdkCgYEAsriXysbxBYyMp05gqEW7
+lHIFbFgpSrs9th+Q5U6wW6JEgYaHWDJ1NslY80MiZI93FWjbkbZ7BvBWESeL3EIL
+a+EMErht0pVCbIhZ6FF4foPAqia0wAJVx14mm+G80kNBp5jE/NnleEsE3KcO7nBb
+hg8gLn+x7bk81JZ0TDrzBYkCgYEAuQKluv47SeF3tSScTfKLPpvcKCWmxe1uutkQ
+7JShPhVioyOMNb39jnYBOWbjkm4d4QgqRuiytSR0oi3QI+Ziy5EYMyNn713qAk9j
+r2TJZDDPDKnBW+zt4YI4EohWMXk3JRUW4XDKggjjwJQA7bZ812TtHHvP/xoThfG7
+eSNb3eECgYBw6ssgCtMrdvQiEmjKVX/9yI38mvC2kSGyzbrQnGUfgqRGomRpeZuD
+B5E3kysA4td5pT5lvcLgSW0TbOz+YbiriXjwOihPIelCvc9gE2eOUI71/byUWPFz
+7u5F/xQ4NaGr5suLF+lBC6h7pSbM4El9lIHQAQadpuEdzHqrw+hs3g==
+-----END RSA PRIVATE KEY-----

+ 24 - 0
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_cert.pem

@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID8TCCAtmgAwIBAgIUKXNlBRVe6UepjQUijIFPZBd/4qYwDQYJKoZIhvcNAQEL
+BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2
+YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE
+AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN
+MjIwNTMxMjAwMzE1WhcNNDIwNTI2MjAwMzE1WjCBhzELMAkGA1UEBhMCVVMxCzAJ
+BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx
+ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ
+KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAOOFuIucH7XXfohGxKd3uR/ihUA/LdduR9I8kfpUEbq5BOt8xZe5/Yn9
+a1ozEHVW6cOAbHbnwAR8tkSgZ/t42QIA2k77HWU1Jh2xiEIsJivo3imm4/kZWuR0
+OqPh7MhzxpR/hvNwpI5mJsAVBWFMa5KtecFZLnyZtwHylrRN1QXzuLrOxuKFufK3
+RKbTABScn5RbZL976H/jgfSeXrbt242NrIoBnVe6fRbekbq2DQ6zFArbQMUgHjHK
+P0UqBgdr1QmHfi9KytFyx9BTP3gXWnWIu+bY7/v7qKJMHFwGETo+dCLWYevJL316
+HnLfhApDMfP8U+Yv/y1N/YvgaSOSlEcCAwEAAaNTMFEwHQYDVR0OBBYEFKhAU4nu
+0h/lrnggbIGvx4ej0WklMB8GA1UdIwQYMBaAFKhAU4nu0h/lrnggbIGvx4ej0Wkl
+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAE/6NghzQ5fu6yR6
+EHKbj/YMrFdT7aGn5n2sAf7wJ33LIhiFHkpWBsVlm7rDtZtwhe891ZK/P60anlg9
+/P0Ua53tSRVRmCvTnEbXWOVMN4is6MsR7BlmzUxl4AtIn7jbeifEwRL7B4xDYmdA
+QrQnsqoz45dLgS5xK4WDqXATP09Q91xQDuhud/b+A4jrvgwFASmL7rMIZbp4f1JQ
+nlnl/9VoTBQBvJiWkDUtQDMpRLtauddEkv4AGz75p5IspXWD6cOemuh2iQec11xD
+X20rs2WZbAcAiUa3nmy8OKYw435vmpj8gp39WYbX/Yx9TymrFFbVY92wYn+quTco
+pKklVz0=
+-----END CERTIFICATE-----

+ 27 - 0
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_key.pem

@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEA44W4i5wftdd+iEbEp3e5H+KFQD8t125H0jyR+lQRurkE63zF
+l7n9if1rWjMQdVbpw4BsdufABHy2RKBn+3jZAgDaTvsdZTUmHbGIQiwmK+jeKabj
++Rla5HQ6o+HsyHPGlH+G83CkjmYmwBUFYUxrkq15wVkufJm3AfKWtE3VBfO4us7G
+4oW58rdEptMAFJyflFtkv3vof+OB9J5etu3bjY2sigGdV7p9Ft6RurYNDrMUCttA
+xSAeMco/RSoGB2vVCYd+L0rK0XLH0FM/eBdadYi75tjv+/uookwcXAYROj50ItZh
+68kvfXoect+ECkMx8/xT5i//LU39i+BpI5KURwIDAQABAoIBABgyjo/6iLzUMFbZ
+/+w3pW6orrdIgN2akvTfED9pVYFgUA+jc3hRhY95bkNnjuaL2cy7Cc4Tk65mfRQL
+Y0OxdJLr+EvSFSxAXM9npDA1ddHRsF8JqtFBSxNk8R+g1Yf0GDiO35Fgd3/ViWWA
+VtQkRoSRApP3oiQKTRZd8H04keFR+PvmDk/Lq11l3Kc24A1PevKIPX1oI990ggw9
+9i4uSV+cnuMxmcI9xxJtgwdDFdjr39l2arLOHr4s6LGoV2IOdXHNlv5xRqWUZ0FH
+MDHowkLgwDrdSTnNeaVNkce14Gqx+bd4hNaLCdKXMpedBTEmrut3f3hdV1kKjaKt
+aqRYr8ECgYEA/YDGZY2jvFoHHBywlqmEMFrrCvQGH51m5R1Ntpkzr+Rh3YCmrpvq
+xgwJXING0PUw3dz+xrH5lJICrfNE5Kt3fPu1rAEy+13mYsNowghtUq2Rtu0Hsjjx
+2E3Bf8vEB6RNBMmGkUpTTIAroGF5tpJoRvfnWax+k4pFdrKYFtyZdNcCgYEA5cNv
+EPltvOobjTXlUmtVP3n27KZN2aXexTcagLzRxE9CV4cYySENl3KuOMmccaZpIl6z
+aHk6BT4X+M0LqElNUczrInfVqI+SGAFLGy7W6CJaqSr6cpyFUP/fosKpm6wKGgLq
+udHfpvz5rckhKd8kJxFLvhGOK9yN5qpzih0gfhECgYAJfwRvk3G5wYmYpP58dlcs
+VIuPenqsPoI3PPTHTU/hW+XKnWIhElgmGRdUrto9Q6IT/Y5RtSMLTLjq+Tzwb/fm
+56rziYv2XJsfwgAvnI8z1Kqrto9ePsHYf3krJ1/thVsZPc9bq/QY3ohD1sLvcuaT
+GgBBnLOVJU3a12/ZE2RwOwKBgF0csWMAoj8/5IB6if+3ral2xOGsl7oPZVMo/J2V
+Z7EVqb4M6rd/pKFugTpUQgkwtkSOekhpcGD1hAN5HTNK2YG/+L5UMAsKe9sskwJm
+HgOfAHy0BSDzW3ey6i9skg2bT9Cww+0gJ3Hl7U1HSCBO5LjMYpSZSrNtwzfqdb5Q
+BX3xAoGARZdR28Ej3+/+0+fz47Yu2h4z0EI/EbrudLOWY936jIeAVwHckI3+BuqH
+qR4poj1gfbnMxNuI9UzIXzjEmGewx9kDZ7IYnvloZKqoVQODO5GlKF2ja6IcMNlh
+GCNdD6PSAS6HcmalmWo9sj+1YMkrl+GJikKZqVBHrHNwMGAG67w=
+-----END RSA PRIVATE KEY-----

+ 24 - 0
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_cert.pem

@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID8TCCAtmgAwIBAgIUKCoDuLtiZXvhsBY2RoDm0ugizJ8wDQYJKoZIhvcNAQEL
+BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2
+YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE
+AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN
+MjIwNTMxMjAwODI1WhcNNDIwNTI2MjAwODI1WjCBhzELMAkGA1UEBhMCVVMxCzAJ
+BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx
+ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ
+KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAKK1++PXQ+M3hjYH/v0K4UEYl5ljzpNM1i52eQM+gFooojT87PDSaphT
+fs0PXy/PTAjHBEvPhWpOpmQXfJNYzjwcCvg66hbqkv++/VTZiFLAsHagzkEz+FRJ
+qT5Eq7G5FLyw1izX1uxyPN7tAEWEEg7eqsiaXD3Cq8+TYN9cjirPeF7RZF8yFCYE
+xqvbo+Yc6RL6xw19iXVTfctRgQe581KQuIY5/LXo3dWDEilFdsADAe8XAEcO64es
+Ow0g1UvXLnpXSE151kXBFb3sKH/ZjCecDYMCIMEb4sWLSblkSxJ5sNSmXIG4wtr2
+Qnii7CXZgnVYraQE/Jyh+NMQANuoSdMCAwEAAaNTMFEwHQYDVR0OBBYEFAyQQQuM
+ab+YUQqjK8dVVOoHVFmXMB8GA1UdIwQYMBaAFAyQQQuMab+YUQqjK8dVVOoHVFmX
+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADj0vQ6ykWhicoqR
+e6VZMwlEJV7/DSvWWKBd9MUjfKye0A4565ya5lmnzP3DiD3nqGe3miqmLsXKDs+X
+POqlPXTWIamP7D4MJ32XtSLwZB4ru+I+Ao/P/VngPepoRPQoBnzHe7jww0rokqxl
+AZERjlbTUwUAy/BPWPSzSJZ2j0tcs6ZLDNyYzpK4ao8R9/1VmQ92Tcp3feJs1QTg
+odRQc3om/AkWOwsll+oyX0UbJeHkFHiLanUPXbdh+/BkSvZJ8ynL+feSDdaurPe+
+PSfnqLtQft9/neecGRdEaQzzzSFVQUVQzTdK1Q7hA7b55b2HvIa3ktDiks+sJsYN
+Dhm6uZM=
+-----END CERTIFICATE-----

+ 27 - 0
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_key.pem

@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAorX749dD4zeGNgf+/QrhQRiXmWPOk0zWLnZ5Az6AWiiiNPzs
+8NJqmFN+zQ9fL89MCMcES8+Fak6mZBd8k1jOPBwK+DrqFuqS/779VNmIUsCwdqDO
+QTP4VEmpPkSrsbkUvLDWLNfW7HI83u0ARYQSDt6qyJpcPcKrz5Ng31yOKs94XtFk
+XzIUJgTGq9uj5hzpEvrHDX2JdVN9y1GBB7nzUpC4hjn8tejd1YMSKUV2wAMB7xcA
+Rw7rh6w7DSDVS9cueldITXnWRcEVvewof9mMJ5wNgwIgwRvixYtJuWRLEnmw1KZc
+gbjC2vZCeKLsJdmCdVitpAT8nKH40xAA26hJ0wIDAQABAoIBACaNR+lsD8G+XiZf
+LqN1+HkcAo9tfnyYMAdCOtnx7SdviT9Uzi8hK/B7mAeuJLeHPlS2EuaDfPD7QaFl
+jza6S+MiIdc+3kgfvESsVAnOoOY6kZUJ9NSuI6CU82y1iJjLaYZrv9NQMLRFPPb0
+4KOX709mosB1EnXvshW0rbc+jtDFhrm1SxMt+k9TuzmMxjbOeW4LOLXPgU8X1T3Q
+Xy0hMZZtcgBs9wFIo8yCtmOixax9pnFE8rRltgDxTodn9LLdz1FieyntNgDksZ0P
+nt4kV7Mqly7ELaea+Foaj244mKsesic2e3GhAlMRLun/VSunSf7mOCxfpITB8dp1
+drDhOYECgYEA19151dVxRcviuovN6Dar+QszMTnU8pDJ8BjLFjXjP/hNBBwMTHDE
+duMuWk2qnwZqMooI/shxrF/ufmTgS0CFrh2+ANBZu27vWConJNXcyNtdigI4wt50
+L0Y2qcZn2mg67qFXHwoR3QNwrwnPwEjRXA09at9CSRZzcwDQ0ETXhYsCgYEAwPaG
+06QdK8Zyly7TTzZJwxzv9uGiqzodmGtX6NEKjgij2JaCxHpukqZBJoqa0jKeK1cm
+eNVkOvT5ff9TMzarSHQLr3pZen2/oVLb5gaFkbcJt/klv9Fd+ZRilHY3i6QwS6pD
+uMiPOWS4DrLHDRVoVlAZTDjT1RVwwTs+P2NhJdkCgYEAsriXysbxBYyMp05gqEW7
+lHIFbFgpSrs9th+Q5U6wW6JEgYaHWDJ1NslY80MiZI93FWjbkbZ7BvBWESeL3EIL
+a+EMErht0pVCbIhZ6FF4foPAqia0wAJVx14mm+G80kNBp5jE/NnleEsE3KcO7nBb
+hg8gLn+x7bk81JZ0TDrzBYkCgYEAuQKluv47SeF3tSScTfKLPpvcKCWmxe1uutkQ
+7JShPhVioyOMNb39jnYBOWbjkm4d4QgqRuiytSR0oi3QI+Ziy5EYMyNn713qAk9j
+r2TJZDDPDKnBW+zt4YI4EohWMXk3JRUW4XDKggjjwJQA7bZ812TtHHvP/xoThfG7
+eSNb3eECgYBw6ssgCtMrdvQiEmjKVX/9yI38mvC2kSGyzbrQnGUfgqRGomRpeZuD
+B5E3kysA4td5pT5lvcLgSW0TbOz+YbiriXjwOihPIelCvc9gE2eOUI71/byUWPFz
+7u5F/xQ4NaGr5suLF+lBC6h7pSbM4El9lIHQAQadpuEdzHqrw+hs3g==
+-----END RSA PRIVATE KEY-----

+ 404 - 0
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/tlsconfigstore.go

@@ -0,0 +1,404 @@
+/*
+ *
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package tlsconfigstore offloads operations to S2Av2.
+package tlsconfigstore
+
+import (
+	"crypto/tls"
+	"crypto/x509"
+	"encoding/pem"
+	"errors"
+	"fmt"
+
+	"github.com/google/s2a-go/internal/tokenmanager"
+	"github.com/google/s2a-go/internal/v2/certverifier"
+	"github.com/google/s2a-go/internal/v2/remotesigner"
+	"github.com/google/s2a-go/stream"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/grpclog"
+
+	commonpbv1 "github.com/google/s2a-go/internal/proto/common_go_proto"
+	commonpb "github.com/google/s2a-go/internal/proto/v2/common_go_proto"
+	s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto"
+)
+
+const (
+	// HTTP/2
+	h2 = "h2"
+)
+
+// GetTLSConfigurationForClient returns a tls.Config instance for use by a client application.
+func GetTLSConfigurationForClient(serverHostname string, s2AStream stream.S2AStream, tokenManager tokenmanager.AccessTokenManager, localIdentity *commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, serverAuthorizationPolicy []byte) (*tls.Config, error) {
+	authMechanisms := getAuthMechanisms(tokenManager, []*commonpbv1.Identity{localIdentity})
+
+	if grpclog.V(1) {
+		grpclog.Infof("Sending request to S2Av2 for client TLS config.")
+	}
+	// Send request to S2Av2 for config.
+	if err := s2AStream.Send(&s2av2pb.SessionReq{
+		LocalIdentity:            localIdentity,
+		AuthenticationMechanisms: authMechanisms,
+		ReqOneof: &s2av2pb.SessionReq_GetTlsConfigurationReq{
+			GetTlsConfigurationReq: &s2av2pb.GetTlsConfigurationReq{
+				ConnectionSide: commonpb.ConnectionSide_CONNECTION_SIDE_CLIENT,
+			},
+		},
+	}); err != nil {
+		grpclog.Infof("Failed to send request to S2Av2 for client TLS config")
+		return nil, err
+	}
+
+	// Get the response containing config from S2Av2.
+	resp, err := s2AStream.Recv()
+	if err != nil {
+		grpclog.Infof("Failed to receive client TLS config response from S2Av2.")
+		return nil, err
+	}
+
+	// TODO(rmehta19): Add unit test for this if statement.
+	if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) {
+		return nil, fmt.Errorf("failed to get TLS configuration from S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details)
+	}
+
+	// Extract TLS configiguration from SessionResp.
+	tlsConfig := resp.GetGetTlsConfigurationResp().GetClientTlsConfiguration()
+
+	var cert tls.Certificate
+	for i, v := range tlsConfig.CertificateChain {
+		// Populate Certificates field.
+		block, _ := pem.Decode([]byte(v))
+		if block == nil {
+			return nil, errors.New("certificate in CertificateChain obtained from S2Av2 is empty")
+		}
+		x509Cert, err := x509.ParseCertificate(block.Bytes)
+		if err != nil {
+			return nil, err
+		}
+		cert.Certificate = append(cert.Certificate, x509Cert.Raw)
+		if i == 0 {
+			cert.Leaf = x509Cert
+		}
+	}
+
+	if len(tlsConfig.CertificateChain) > 0 {
+		cert.PrivateKey = remotesigner.New(cert.Leaf, s2AStream)
+		if cert.PrivateKey == nil {
+			return nil, errors.New("failed to retrieve Private Key from Remote Signer Library")
+		}
+	}
+
+	minVersion, maxVersion, err := getTLSMinMaxVersionsClient(tlsConfig)
+	if err != nil {
+		return nil, err
+	}
+
+	// Create mTLS credentials for client.
+	config := &tls.Config{
+		VerifyPeerCertificate:  certverifier.VerifyServerCertificateChain(serverHostname, verificationMode, s2AStream, serverAuthorizationPolicy),
+		ServerName:             serverHostname,
+		InsecureSkipVerify:     true, // NOLINT
+		ClientSessionCache:     nil,
+		SessionTicketsDisabled: true,
+		MinVersion:             minVersion,
+		MaxVersion:             maxVersion,
+		NextProtos:             []string{h2},
+	}
+	if len(tlsConfig.CertificateChain) > 0 {
+		config.Certificates = []tls.Certificate{cert}
+	}
+	return config, nil
+}
+
+// GetTLSConfigurationForServer returns a tls.Config instance for use by a server application.
+func GetTLSConfigurationForServer(s2AStream stream.S2AStream, tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode) (*tls.Config, error) {
+	return &tls.Config{
+		GetConfigForClient: ClientConfig(tokenManager, localIdentities, verificationMode, s2AStream),
+	}, nil
+}
+
+// ClientConfig builds a TLS config for a server to establish a secure
+// connection with a client, based on SNI communicated during ClientHello.
+// Ensures that server presents the correct certificate to establish a TLS
+// connection.
+func ClientConfig(tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, s2AStream stream.S2AStream) func(chi *tls.ClientHelloInfo) (*tls.Config, error) {
+	return func(chi *tls.ClientHelloInfo) (*tls.Config, error) {
+		tlsConfig, err := getServerConfigFromS2Av2(tokenManager, localIdentities, chi.ServerName, s2AStream)
+		if err != nil {
+			return nil, err
+		}
+
+		var cert tls.Certificate
+		for i, v := range tlsConfig.CertificateChain {
+			// Populate Certificates field.
+			block, _ := pem.Decode([]byte(v))
+			if block == nil {
+				return nil, errors.New("certificate in CertificateChain obtained from S2Av2 is empty")
+			}
+			x509Cert, err := x509.ParseCertificate(block.Bytes)
+			if err != nil {
+				return nil, err
+			}
+			cert.Certificate = append(cert.Certificate, x509Cert.Raw)
+			if i == 0 {
+				cert.Leaf = x509Cert
+			}
+		}
+
+		cert.PrivateKey = remotesigner.New(cert.Leaf, s2AStream)
+		if cert.PrivateKey == nil {
+			return nil, errors.New("failed to retrieve Private Key from Remote Signer Library")
+		}
+
+		minVersion, maxVersion, err := getTLSMinMaxVersionsServer(tlsConfig)
+		if err != nil {
+			return nil, err
+		}
+
+		clientAuth := getTLSClientAuthType(tlsConfig)
+
+		var cipherSuites []uint16
+		cipherSuites = getCipherSuites(tlsConfig.Ciphersuites)
+
+		// Create mTLS credentials for server.
+		return &tls.Config{
+			Certificates:           []tls.Certificate{cert},
+			VerifyPeerCertificate:  certverifier.VerifyClientCertificateChain(verificationMode, s2AStream),
+			ClientAuth:             clientAuth,
+			CipherSuites:           cipherSuites,
+			SessionTicketsDisabled: true,
+			MinVersion:             minVersion,
+			MaxVersion:             maxVersion,
+			NextProtos:             []string{h2},
+		}, nil
+	}
+}
+
+func getCipherSuites(tlsConfigCipherSuites []commonpb.Ciphersuite) []uint16 {
+	var tlsGoCipherSuites []uint16
+	for _, v := range tlsConfigCipherSuites {
+		s := getTLSCipherSuite(v)
+		if s != 0xffff {
+			tlsGoCipherSuites = append(tlsGoCipherSuites, s)
+		}
+	}
+	return tlsGoCipherSuites
+}
+
+func getTLSCipherSuite(tlsCipherSuite commonpb.Ciphersuite) uint16 {
+	switch tlsCipherSuite {
+	case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+		return tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+	case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+		return tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+	case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
+		return tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+	case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+		return tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+	case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+		return tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+	case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+		return tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+	default:
+		return 0xffff
+	}
+}
+
+func getServerConfigFromS2Av2(tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity, sni string, s2AStream stream.S2AStream) (*s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration, error) {
+	authMechanisms := getAuthMechanisms(tokenManager, localIdentities)
+	var locID *commonpbv1.Identity
+	if localIdentities != nil {
+		locID = localIdentities[0]
+	}
+
+	if err := s2AStream.Send(&s2av2pb.SessionReq{
+		LocalIdentity:            locID,
+		AuthenticationMechanisms: authMechanisms,
+		ReqOneof: &s2av2pb.SessionReq_GetTlsConfigurationReq{
+			GetTlsConfigurationReq: &s2av2pb.GetTlsConfigurationReq{
+				ConnectionSide: commonpb.ConnectionSide_CONNECTION_SIDE_SERVER,
+				Sni:            sni,
+			},
+		},
+	}); err != nil {
+		return nil, err
+	}
+
+	resp, err := s2AStream.Recv()
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO(rmehta19): Add unit test for this if statement.
+	if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) {
+		return nil, fmt.Errorf("failed to get TLS configuration from S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details)
+	}
+
+	return resp.GetGetTlsConfigurationResp().GetServerTlsConfiguration(), nil
+}
+
+func getTLSClientAuthType(tlsConfig *s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration) tls.ClientAuthType {
+	var clientAuth tls.ClientAuthType
+	switch x := tlsConfig.RequestClientCertificate; x {
+	case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_DONT_REQUEST_CLIENT_CERTIFICATE:
+		clientAuth = tls.NoClientCert
+	case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
+		clientAuth = tls.RequestClientCert
+	case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
+		// This case actually maps to tls.VerifyClientCertIfGiven. However this
+		// mapping triggers normal verification, followed by custom verification,
+		// specified in VerifyPeerCertificate. To bypass normal verification, and
+		// only do custom verification we set clientAuth to RequireAnyClientCert or
+		// RequestClientCert. See https://github.com/google/s2a-go/pull/43 for full
+		// discussion.
+		clientAuth = tls.RequireAnyClientCert
+	case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
+		clientAuth = tls.RequireAnyClientCert
+	case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
+		// This case actually maps to tls.RequireAndVerifyClientCert. However this
+		// mapping triggers normal verification, followed by custom verification,
+		// specified in VerifyPeerCertificate. To bypass normal verification, and
+		// only do custom verification we set clientAuth to RequireAnyClientCert or
+		// RequestClientCert. See https://github.com/google/s2a-go/pull/43 for full
+		// discussion.
+		clientAuth = tls.RequireAnyClientCert
+	default:
+		clientAuth = tls.RequireAnyClientCert
+	}
+	return clientAuth
+}
+
+func getAuthMechanisms(tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity) []*s2av2pb.AuthenticationMechanism {
+	if tokenManager == nil {
+		return nil
+	}
+	if len(localIdentities) == 0 {
+		token, err := tokenManager.DefaultToken()
+		if err != nil {
+			grpclog.Infof("Unable to get token for empty local identity: %v", err)
+			return nil
+		}
+		return []*s2av2pb.AuthenticationMechanism{
+			{
+				MechanismOneof: &s2av2pb.AuthenticationMechanism_Token{
+					Token: token,
+				},
+			},
+		}
+	}
+	var authMechanisms []*s2av2pb.AuthenticationMechanism
+	for _, localIdentity := range localIdentities {
+		if localIdentity == nil {
+			token, err := tokenManager.DefaultToken()
+			if err != nil {
+				grpclog.Infof("Unable to get default token for local identity %v: %v", localIdentity, err)
+				continue
+			}
+			authMechanisms = append(authMechanisms, &s2av2pb.AuthenticationMechanism{
+				Identity: localIdentity,
+				MechanismOneof: &s2av2pb.AuthenticationMechanism_Token{
+					Token: token,
+				},
+			})
+		} else {
+			token, err := tokenManager.Token(localIdentity)
+			if err != nil {
+				grpclog.Infof("Unable to get token for local identity %v: %v", localIdentity, err)
+				continue
+			}
+			authMechanisms = append(authMechanisms, &s2av2pb.AuthenticationMechanism{
+				Identity: localIdentity,
+				MechanismOneof: &s2av2pb.AuthenticationMechanism_Token{
+					Token: token,
+				},
+			})
+		}
+	}
+	return authMechanisms
+}
+
+// TODO(rmehta19): refactor switch statements into a helper function.
+func getTLSMinMaxVersionsClient(tlsConfig *s2av2pb.GetTlsConfigurationResp_ClientTlsConfiguration) (uint16, uint16, error) {
+	// Map S2Av2 TLSVersion to consts defined in tls package.
+	var minVersion uint16
+	var maxVersion uint16
+	switch x := tlsConfig.MinTlsVersion; x {
+	case commonpb.TLSVersion_TLS_VERSION_1_0:
+		minVersion = tls.VersionTLS10
+	case commonpb.TLSVersion_TLS_VERSION_1_1:
+		minVersion = tls.VersionTLS11
+	case commonpb.TLSVersion_TLS_VERSION_1_2:
+		minVersion = tls.VersionTLS12
+	case commonpb.TLSVersion_TLS_VERSION_1_3:
+		minVersion = tls.VersionTLS13
+	default:
+		return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MinTlsVersion: %v", x)
+	}
+
+	switch x := tlsConfig.MaxTlsVersion; x {
+	case commonpb.TLSVersion_TLS_VERSION_1_0:
+		maxVersion = tls.VersionTLS10
+	case commonpb.TLSVersion_TLS_VERSION_1_1:
+		maxVersion = tls.VersionTLS11
+	case commonpb.TLSVersion_TLS_VERSION_1_2:
+		maxVersion = tls.VersionTLS12
+	case commonpb.TLSVersion_TLS_VERSION_1_3:
+		maxVersion = tls.VersionTLS13
+	default:
+		return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MaxTlsVersion: %v", x)
+	}
+	if minVersion > maxVersion {
+		return minVersion, maxVersion, errors.New("S2Av2 provided minVersion > maxVersion")
+	}
+	return minVersion, maxVersion, nil
+}
+
+func getTLSMinMaxVersionsServer(tlsConfig *s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration) (uint16, uint16, error) {
+	// Map S2Av2 TLSVersion to consts defined in tls package.
+	var minVersion uint16
+	var maxVersion uint16
+	switch x := tlsConfig.MinTlsVersion; x {
+	case commonpb.TLSVersion_TLS_VERSION_1_0:
+		minVersion = tls.VersionTLS10
+	case commonpb.TLSVersion_TLS_VERSION_1_1:
+		minVersion = tls.VersionTLS11
+	case commonpb.TLSVersion_TLS_VERSION_1_2:
+		minVersion = tls.VersionTLS12
+	case commonpb.TLSVersion_TLS_VERSION_1_3:
+		minVersion = tls.VersionTLS13
+	default:
+		return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MinTlsVersion: %v", x)
+	}
+
+	switch x := tlsConfig.MaxTlsVersion; x {
+	case commonpb.TLSVersion_TLS_VERSION_1_0:
+		maxVersion = tls.VersionTLS10
+	case commonpb.TLSVersion_TLS_VERSION_1_1:
+		maxVersion = tls.VersionTLS11
+	case commonpb.TLSVersion_TLS_VERSION_1_2:
+		maxVersion = tls.VersionTLS12
+	case commonpb.TLSVersion_TLS_VERSION_1_3:
+		maxVersion = tls.VersionTLS13
+	default:
+		return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MaxTlsVersion: %v", x)
+	}
+	if minVersion > maxVersion {
+		return minVersion, maxVersion, errors.New("S2Av2 provided minVersion > maxVersion")
+	}
+	return minVersion, maxVersion, nil
+}

+ 412 - 0
vendor/github.com/google/s2a-go/s2a.go

@@ -0,0 +1,412 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package s2a provides the S2A transport credentials used by a gRPC
+// application.
+package s2a
+
+import (
+	"context"
+	"crypto/tls"
+	"errors"
+	"fmt"
+	"net"
+	"sync"
+	"time"
+
+	"github.com/golang/protobuf/proto"
+	"github.com/google/s2a-go/fallback"
+	"github.com/google/s2a-go/internal/handshaker"
+	"github.com/google/s2a-go/internal/handshaker/service"
+	"github.com/google/s2a-go/internal/tokenmanager"
+	"github.com/google/s2a-go/internal/v2"
+	"google.golang.org/grpc/credentials"
+	"google.golang.org/grpc/grpclog"
+
+	commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
+	s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto"
+)
+
+const (
+	s2aSecurityProtocol = "tls"
+	// defaultTimeout specifies the default server handshake timeout.
+	defaultTimeout = 30.0 * time.Second
+)
+
+// s2aTransportCreds are the transport credentials required for establishing
+// a secure connection using the S2A. They implement the
+// credentials.TransportCredentials interface.
+type s2aTransportCreds struct {
+	info          *credentials.ProtocolInfo
+	minTLSVersion commonpb.TLSVersion
+	maxTLSVersion commonpb.TLSVersion
+	// tlsCiphersuites contains the ciphersuites used in the S2A connection.
+	// Note that these are currently unconfigurable.
+	tlsCiphersuites []commonpb.Ciphersuite
+	// localIdentity should only be used by the client.
+	localIdentity *commonpb.Identity
+	// localIdentities should only be used by the server.
+	localIdentities []*commonpb.Identity
+	// targetIdentities should only be used by the client.
+	targetIdentities            []*commonpb.Identity
+	isClient                    bool
+	s2aAddr                     string
+	ensureProcessSessionTickets *sync.WaitGroup
+}
+
+// NewClientCreds returns a client-side transport credentials object that uses
+// the S2A to establish a secure connection with a server.
+func NewClientCreds(opts *ClientOptions) (credentials.TransportCredentials, error) {
+	if opts == nil {
+		return nil, errors.New("nil client options")
+	}
+	var targetIdentities []*commonpb.Identity
+	for _, targetIdentity := range opts.TargetIdentities {
+		protoTargetIdentity, err := toProtoIdentity(targetIdentity)
+		if err != nil {
+			return nil, err
+		}
+		targetIdentities = append(targetIdentities, protoTargetIdentity)
+	}
+	localIdentity, err := toProtoIdentity(opts.LocalIdentity)
+	if err != nil {
+		return nil, err
+	}
+	if opts.EnableLegacyMode {
+		return &s2aTransportCreds{
+			info: &credentials.ProtocolInfo{
+				SecurityProtocol: s2aSecurityProtocol,
+			},
+			minTLSVersion: commonpb.TLSVersion_TLS1_3,
+			maxTLSVersion: commonpb.TLSVersion_TLS1_3,
+			tlsCiphersuites: []commonpb.Ciphersuite{
+				commonpb.Ciphersuite_AES_128_GCM_SHA256,
+				commonpb.Ciphersuite_AES_256_GCM_SHA384,
+				commonpb.Ciphersuite_CHACHA20_POLY1305_SHA256,
+			},
+			localIdentity:               localIdentity,
+			targetIdentities:            targetIdentities,
+			isClient:                    true,
+			s2aAddr:                     opts.S2AAddress,
+			ensureProcessSessionTickets: opts.EnsureProcessSessionTickets,
+		}, nil
+	}
+	verificationMode := getVerificationMode(opts.VerificationMode)
+	var fallbackFunc fallback.ClientHandshake
+	if opts.FallbackOpts != nil && opts.FallbackOpts.FallbackClientHandshakeFunc != nil {
+		fallbackFunc = opts.FallbackOpts.FallbackClientHandshakeFunc
+	}
+	return v2.NewClientCreds(opts.S2AAddress, localIdentity, verificationMode, fallbackFunc, opts.getS2AStream, opts.serverAuthorizationPolicy)
+}
+
+// NewServerCreds returns a server-side transport credentials object that uses
+// the S2A to establish a secure connection with a client.
+func NewServerCreds(opts *ServerOptions) (credentials.TransportCredentials, error) {
+	if opts == nil {
+		return nil, errors.New("nil server options")
+	}
+	var localIdentities []*commonpb.Identity
+	for _, localIdentity := range opts.LocalIdentities {
+		protoLocalIdentity, err := toProtoIdentity(localIdentity)
+		if err != nil {
+			return nil, err
+		}
+		localIdentities = append(localIdentities, protoLocalIdentity)
+	}
+	if opts.EnableLegacyMode {
+		return &s2aTransportCreds{
+			info: &credentials.ProtocolInfo{
+				SecurityProtocol: s2aSecurityProtocol,
+			},
+			minTLSVersion: commonpb.TLSVersion_TLS1_3,
+			maxTLSVersion: commonpb.TLSVersion_TLS1_3,
+			tlsCiphersuites: []commonpb.Ciphersuite{
+				commonpb.Ciphersuite_AES_128_GCM_SHA256,
+				commonpb.Ciphersuite_AES_256_GCM_SHA384,
+				commonpb.Ciphersuite_CHACHA20_POLY1305_SHA256,
+			},
+			localIdentities: localIdentities,
+			isClient:        false,
+			s2aAddr:         opts.S2AAddress,
+		}, nil
+	}
+	verificationMode := getVerificationMode(opts.VerificationMode)
+	return v2.NewServerCreds(opts.S2AAddress, localIdentities, verificationMode, opts.getS2AStream)
+}
+
+// ClientHandshake initiates a client-side TLS handshake using the S2A.
+func (c *s2aTransportCreds) ClientHandshake(ctx context.Context, serverAuthority string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
+	if !c.isClient {
+		return nil, nil, errors.New("client handshake called using server transport credentials")
+	}
+
+	// Connect to the S2A.
+	hsConn, err := service.Dial(c.s2aAddr)
+	if err != nil {
+		grpclog.Infof("Failed to connect to S2A: %v", err)
+		return nil, nil, err
+	}
+
+	var cancel context.CancelFunc
+	ctx, cancel = context.WithCancel(ctx)
+	defer cancel()
+
+	opts := &handshaker.ClientHandshakerOptions{
+		MinTLSVersion:               c.minTLSVersion,
+		MaxTLSVersion:               c.maxTLSVersion,
+		TLSCiphersuites:             c.tlsCiphersuites,
+		TargetIdentities:            c.targetIdentities,
+		LocalIdentity:               c.localIdentity,
+		TargetName:                  serverAuthority,
+		EnsureProcessSessionTickets: c.ensureProcessSessionTickets,
+	}
+	chs, err := handshaker.NewClientHandshaker(ctx, hsConn, rawConn, c.s2aAddr, opts)
+	if err != nil {
+		grpclog.Infof("Call to handshaker.NewClientHandshaker failed: %v", err)
+		return nil, nil, err
+	}
+	defer func() {
+		if err != nil {
+			if closeErr := chs.Close(); closeErr != nil {
+				grpclog.Infof("Close failed unexpectedly: %v", err)
+				err = fmt.Errorf("%v: close unexpectedly failed: %v", err, closeErr)
+			}
+		}
+	}()
+
+	secConn, authInfo, err := chs.ClientHandshake(context.Background())
+	if err != nil {
+		grpclog.Infof("Handshake failed: %v", err)
+		return nil, nil, err
+	}
+	return secConn, authInfo, nil
+}
+
+// ServerHandshake initiates a server-side TLS handshake using the S2A.
+func (c *s2aTransportCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
+	if c.isClient {
+		return nil, nil, errors.New("server handshake called using client transport credentials")
+	}
+
+	// Connect to the S2A.
+	hsConn, err := service.Dial(c.s2aAddr)
+	if err != nil {
+		grpclog.Infof("Failed to connect to S2A: %v", err)
+		return nil, nil, err
+	}
+
+	ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
+	defer cancel()
+
+	opts := &handshaker.ServerHandshakerOptions{
+		MinTLSVersion:   c.minTLSVersion,
+		MaxTLSVersion:   c.maxTLSVersion,
+		TLSCiphersuites: c.tlsCiphersuites,
+		LocalIdentities: c.localIdentities,
+	}
+	shs, err := handshaker.NewServerHandshaker(ctx, hsConn, rawConn, c.s2aAddr, opts)
+	if err != nil {
+		grpclog.Infof("Call to handshaker.NewServerHandshaker failed: %v", err)
+		return nil, nil, err
+	}
+	defer func() {
+		if err != nil {
+			if closeErr := shs.Close(); closeErr != nil {
+				grpclog.Infof("Close failed unexpectedly: %v", err)
+				err = fmt.Errorf("%v: close unexpectedly failed: %v", err, closeErr)
+			}
+		}
+	}()
+
+	secConn, authInfo, err := shs.ServerHandshake(context.Background())
+	if err != nil {
+		grpclog.Infof("Handshake failed: %v", err)
+		return nil, nil, err
+	}
+	return secConn, authInfo, nil
+}
+
+func (c *s2aTransportCreds) Info() credentials.ProtocolInfo {
+	return *c.info
+}
+
+func (c *s2aTransportCreds) Clone() credentials.TransportCredentials {
+	info := *c.info
+	var localIdentity *commonpb.Identity
+	if c.localIdentity != nil {
+		localIdentity = proto.Clone(c.localIdentity).(*commonpb.Identity)
+	}
+	var localIdentities []*commonpb.Identity
+	if c.localIdentities != nil {
+		localIdentities = make([]*commonpb.Identity, len(c.localIdentities))
+		for i, localIdentity := range c.localIdentities {
+			localIdentities[i] = proto.Clone(localIdentity).(*commonpb.Identity)
+		}
+	}
+	var targetIdentities []*commonpb.Identity
+	if c.targetIdentities != nil {
+		targetIdentities = make([]*commonpb.Identity, len(c.targetIdentities))
+		for i, targetIdentity := range c.targetIdentities {
+			targetIdentities[i] = proto.Clone(targetIdentity).(*commonpb.Identity)
+		}
+	}
+	return &s2aTransportCreds{
+		info:             &info,
+		minTLSVersion:    c.minTLSVersion,
+		maxTLSVersion:    c.maxTLSVersion,
+		tlsCiphersuites:  c.tlsCiphersuites,
+		localIdentity:    localIdentity,
+		localIdentities:  localIdentities,
+		targetIdentities: targetIdentities,
+		isClient:         c.isClient,
+		s2aAddr:          c.s2aAddr,
+	}
+}
+
+func (c *s2aTransportCreds) OverrideServerName(serverNameOverride string) error {
+	c.info.ServerName = serverNameOverride
+	return nil
+}
+
+// TLSClientConfigOptions specifies parameters for creating client TLS config.
+type TLSClientConfigOptions struct {
+	// ServerName is required by s2a as the expected name when verifying the hostname found in server's certificate.
+	// 		tlsConfig, _ := factory.Build(ctx, &s2a.TLSClientConfigOptions{
+	//			ServerName: "example.com",
+	//		})
+	ServerName string
+}
+
+// TLSClientConfigFactory defines the interface for a client TLS config factory.
+type TLSClientConfigFactory interface {
+	Build(ctx context.Context, opts *TLSClientConfigOptions) (*tls.Config, error)
+}
+
+// NewTLSClientConfigFactory returns an instance of s2aTLSClientConfigFactory.
+func NewTLSClientConfigFactory(opts *ClientOptions) (TLSClientConfigFactory, error) {
+	if opts == nil {
+		return nil, fmt.Errorf("opts must be non-nil")
+	}
+	if opts.EnableLegacyMode {
+		return nil, fmt.Errorf("NewTLSClientConfigFactory only supports S2Av2")
+	}
+	tokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager()
+	if err != nil {
+		// The only possible error is: access token not set in the environment,
+		// which is okay in environments other than serverless.
+		grpclog.Infof("Access token manager not initialized: %v", err)
+		return &s2aTLSClientConfigFactory{
+			s2av2Address:              opts.S2AAddress,
+			tokenManager:              nil,
+			verificationMode:          getVerificationMode(opts.VerificationMode),
+			serverAuthorizationPolicy: opts.serverAuthorizationPolicy,
+		}, nil
+	}
+	return &s2aTLSClientConfigFactory{
+		s2av2Address:              opts.S2AAddress,
+		tokenManager:              tokenManager,
+		verificationMode:          getVerificationMode(opts.VerificationMode),
+		serverAuthorizationPolicy: opts.serverAuthorizationPolicy,
+	}, nil
+}
+
+type s2aTLSClientConfigFactory struct {
+	s2av2Address              string
+	tokenManager              tokenmanager.AccessTokenManager
+	verificationMode          s2av2pb.ValidatePeerCertificateChainReq_VerificationMode
+	serverAuthorizationPolicy []byte
+}
+
+func (f *s2aTLSClientConfigFactory) Build(
+	ctx context.Context, opts *TLSClientConfigOptions) (*tls.Config, error) {
+	serverName := ""
+	if opts != nil && opts.ServerName != "" {
+		serverName = opts.ServerName
+	}
+	return v2.NewClientTLSConfig(ctx, f.s2av2Address, f.tokenManager, f.verificationMode, serverName, f.serverAuthorizationPolicy)
+}
+
+func getVerificationMode(verificationMode VerificationModeType) s2av2pb.ValidatePeerCertificateChainReq_VerificationMode {
+	switch verificationMode {
+	case ConnectToGoogle:
+		return s2av2pb.ValidatePeerCertificateChainReq_CONNECT_TO_GOOGLE
+	case Spiffe:
+		return s2av2pb.ValidatePeerCertificateChainReq_SPIFFE
+	default:
+		return s2av2pb.ValidatePeerCertificateChainReq_UNSPECIFIED
+	}
+}
+
+// NewS2ADialTLSContextFunc returns a dialer which establishes an MTLS connection using S2A.
+// Example use with http.RoundTripper:
+//
+//		dialTLSContext := s2a.NewS2aDialTLSContextFunc(&s2a.ClientOptions{
+//			S2AAddress:         s2aAddress, // required
+//		})
+//	 	transport := http.DefaultTransport
+//	 	transport.DialTLSContext = dialTLSContext
+func NewS2ADialTLSContextFunc(opts *ClientOptions) func(ctx context.Context, network, addr string) (net.Conn, error) {
+
+	return func(ctx context.Context, network, addr string) (net.Conn, error) {
+
+		fallback := func(err error) (net.Conn, error) {
+			if opts.FallbackOpts != nil && opts.FallbackOpts.FallbackDialer != nil &&
+				opts.FallbackOpts.FallbackDialer.Dialer != nil && opts.FallbackOpts.FallbackDialer.ServerAddr != "" {
+				fbDialer := opts.FallbackOpts.FallbackDialer
+				grpclog.Infof("fall back to dial: %s", fbDialer.ServerAddr)
+				fbConn, fbErr := fbDialer.Dialer.DialContext(ctx, network, fbDialer.ServerAddr)
+				if fbErr != nil {
+					return nil, fmt.Errorf("error fallback to %s: %v; S2A error: %w", fbDialer.ServerAddr, fbErr, err)
+				}
+				return fbConn, nil
+			}
+			return nil, err
+		}
+
+		factory, err := NewTLSClientConfigFactory(opts)
+		if err != nil {
+			grpclog.Infof("error creating S2A client config factory: %v", err)
+			return fallback(err)
+		}
+
+		serverName, _, err := net.SplitHostPort(addr)
+		if err != nil {
+			serverName = addr
+		}
+		timeoutCtx, cancel := context.WithTimeout(ctx, v2.GetS2ATimeout())
+		defer cancel()
+		s2aTLSConfig, err := factory.Build(timeoutCtx, &TLSClientConfigOptions{
+			ServerName: serverName,
+		})
+		if err != nil {
+			grpclog.Infof("error building S2A TLS config: %v", err)
+			return fallback(err)
+		}
+
+		s2aDialer := &tls.Dialer{
+			Config: s2aTLSConfig,
+		}
+		c, err := s2aDialer.DialContext(ctx, network, addr)
+		if err != nil {
+			grpclog.Infof("error dialing with S2A to %s: %v", addr, err)
+			return fallback(err)
+		}
+		grpclog.Infof("success dialing MTLS to %s with S2A", addr)
+		return c, nil
+	}
+}

+ 208 - 0
vendor/github.com/google/s2a-go/s2a_options.go

@@ -0,0 +1,208 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package s2a
+
+import (
+	"context"
+	"crypto/tls"
+	"errors"
+	"sync"
+
+	"github.com/google/s2a-go/fallback"
+	"github.com/google/s2a-go/stream"
+
+	s2apb "github.com/google/s2a-go/internal/proto/common_go_proto"
+)
+
+// Identity is the interface for S2A identities.
+type Identity interface {
+	// Name returns the name of the identity.
+	Name() string
+}
+
+type spiffeID struct {
+	spiffeID string
+}
+
+func (s *spiffeID) Name() string { return s.spiffeID }
+
+// NewSpiffeID creates a SPIFFE ID from id.
+func NewSpiffeID(id string) Identity {
+	return &spiffeID{spiffeID: id}
+}
+
+type hostname struct {
+	hostname string
+}
+
+func (h *hostname) Name() string { return h.hostname }
+
+// NewHostname creates a hostname from name.
+func NewHostname(name string) Identity {
+	return &hostname{hostname: name}
+}
+
+type uid struct {
+	uid string
+}
+
+func (h *uid) Name() string { return h.uid }
+
+// NewUID creates a UID from name.
+func NewUID(name string) Identity {
+	return &uid{uid: name}
+}
+
+// VerificationModeType specifies the mode that S2A must use to verify the peer
+// certificate chain.
+type VerificationModeType int
+
+// Three types of verification modes.
+const (
+	Unspecified = iota
+	ConnectToGoogle
+	Spiffe
+)
+
+// ClientOptions contains the client-side options used to establish a secure
+// channel using the S2A handshaker service.
+type ClientOptions struct {
+	// TargetIdentities contains a list of allowed server identities. One of the
+	// target identities should match the peer identity in the handshake
+	// result; otherwise, the handshake fails.
+	TargetIdentities []Identity
+	// LocalIdentity is the local identity of the client application. If none is
+	// provided, then the S2A will choose the default identity, if one exists.
+	LocalIdentity Identity
+	// S2AAddress is the address of the S2A.
+	S2AAddress string
+	// EnsureProcessSessionTickets waits for all session tickets to be sent to
+	// S2A before a process completes.
+	//
+	// This functionality is crucial for processes that complete very soon after
+	// using S2A to establish a TLS connection, but it can be ignored for longer
+	// lived processes.
+	//
+	// Usage example:
+	//   func main() {
+	//     var ensureProcessSessionTickets sync.WaitGroup
+	//     clientOpts := &s2a.ClientOptions{
+	//       EnsureProcessSessionTickets: &ensureProcessSessionTickets,
+	//       // Set other members.
+	//     }
+	//     creds, _ := s2a.NewClientCreds(clientOpts)
+	//     conn, _ := grpc.Dial(serverAddr, grpc.WithTransportCredentials(creds))
+	//     defer conn.Close()
+	//
+	//     // Make RPC call.
+	//
+	//     // The process terminates right after the RPC call ends.
+	//     // ensureProcessSessionTickets can be used to ensure resumption
+	//     // tickets are fully processed. If the process is long-lived, using
+	//     // ensureProcessSessionTickets is not necessary.
+	//     ensureProcessSessionTickets.Wait()
+	//   }
+	EnsureProcessSessionTickets *sync.WaitGroup
+	// If true, enables the use of legacy S2Av1.
+	EnableLegacyMode bool
+	// VerificationMode specifies the mode that S2A must use to verify the
+	// peer certificate chain.
+	VerificationMode VerificationModeType
+
+	// Optional fallback after dialing with S2A fails.
+	FallbackOpts *FallbackOptions
+
+	// Generates an S2AStream interface for talking to the S2A server.
+	getS2AStream func(ctx context.Context, s2av2Address string) (stream.S2AStream, error)
+
+	// Serialized user specified policy for server authorization.
+	serverAuthorizationPolicy []byte
+}
+
+// FallbackOptions prescribes the fallback logic that should be taken if the application fails to connect with S2A.
+type FallbackOptions struct {
+	// FallbackClientHandshakeFunc is used to specify fallback behavior when calling s2a.NewClientCreds().
+	// It will be called by ClientHandshake function, after handshake with S2A fails.
+	// s2a.NewClientCreds() ignores the other FallbackDialer field.
+	FallbackClientHandshakeFunc fallback.ClientHandshake
+
+	// FallbackDialer is used to specify fallback behavior when calling s2a.NewS2aDialTLSContextFunc().
+	// It passes in a custom fallback dialer and server address to use after dialing with S2A fails.
+	// s2a.NewS2aDialTLSContextFunc() ignores the other FallbackClientHandshakeFunc field.
+	FallbackDialer *FallbackDialer
+}
+
+// FallbackDialer contains a fallback tls.Dialer and a server address to connect to.
+type FallbackDialer struct {
+	// Dialer specifies a fallback tls.Dialer.
+	Dialer *tls.Dialer
+	// ServerAddr is used by Dialer to establish fallback connection.
+	ServerAddr string
+}
+
+// DefaultClientOptions returns the default client options.
+func DefaultClientOptions(s2aAddress string) *ClientOptions {
+	return &ClientOptions{
+		S2AAddress:       s2aAddress,
+		VerificationMode: ConnectToGoogle,
+	}
+}
+
+// ServerOptions contains the server-side options used to establish a secure
+// channel using the S2A handshaker service.
+type ServerOptions struct {
+	// LocalIdentities is the list of local identities that may be assumed by
+	// the server. If no local identity is specified, then the S2A chooses a
+	// default local identity, if one exists.
+	LocalIdentities []Identity
+	// S2AAddress is the address of the S2A.
+	S2AAddress string
+	// If true, enables the use of legacy S2Av1.
+	EnableLegacyMode bool
+	// VerificationMode specifies the mode that S2A must use to verify the
+	// peer certificate chain.
+	VerificationMode VerificationModeType
+
+	// Generates an S2AStream interface for talking to the S2A server.
+	getS2AStream func(ctx context.Context, s2av2Address string) (stream.S2AStream, error)
+}
+
+// DefaultServerOptions returns the default server options.
+func DefaultServerOptions(s2aAddress string) *ServerOptions {
+	return &ServerOptions{
+		S2AAddress:       s2aAddress,
+		VerificationMode: ConnectToGoogle,
+	}
+}
+
+func toProtoIdentity(identity Identity) (*s2apb.Identity, error) {
+	if identity == nil {
+		return nil, nil
+	}
+	switch id := identity.(type) {
+	case *spiffeID:
+		return &s2apb.Identity{IdentityOneof: &s2apb.Identity_SpiffeId{SpiffeId: id.Name()}}, nil
+	case *hostname:
+		return &s2apb.Identity{IdentityOneof: &s2apb.Identity_Hostname{Hostname: id.Name()}}, nil
+	case *uid:
+		return &s2apb.Identity{IdentityOneof: &s2apb.Identity_Uid{Uid: id.Name()}}, nil
+	default:
+		return nil, errors.New("unrecognized identity type")
+	}
+}

+ 79 - 0
vendor/github.com/google/s2a-go/s2a_utils.go

@@ -0,0 +1,79 @@
+/*
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package s2a
+
+import (
+	"context"
+	"errors"
+
+	commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
+	"google.golang.org/grpc/credentials"
+	"google.golang.org/grpc/peer"
+)
+
+// AuthInfo exposes security information from the S2A to the application.
+type AuthInfo interface {
+	// AuthType returns the authentication type.
+	AuthType() string
+	// ApplicationProtocol returns the application protocol, e.g. "grpc".
+	ApplicationProtocol() string
+	// TLSVersion returns the TLS version negotiated during the handshake.
+	TLSVersion() commonpb.TLSVersion
+	// Ciphersuite returns the ciphersuite negotiated during the handshake.
+	Ciphersuite() commonpb.Ciphersuite
+	// PeerIdentity returns the authenticated identity of the peer.
+	PeerIdentity() *commonpb.Identity
+	// LocalIdentity returns the local identity of the application used during
+	// session setup.
+	LocalIdentity() *commonpb.Identity
+	// PeerCertFingerprint returns the SHA256 hash of the peer certificate used in
+	// the S2A handshake.
+	PeerCertFingerprint() []byte
+	// LocalCertFingerprint returns the SHA256 hash of the local certificate used
+	// in the S2A handshake.
+	LocalCertFingerprint() []byte
+	// IsHandshakeResumed returns true if a cached session was used to resume
+	// the handshake.
+	IsHandshakeResumed() bool
+	// SecurityLevel returns the security level of the connection.
+	SecurityLevel() credentials.SecurityLevel
+}
+
+// AuthInfoFromPeer extracts the authinfo.S2AAuthInfo object from the given
+// peer, if it exists. This API should be used by gRPC clients after
+// obtaining a peer object using the grpc.Peer() CallOption.
+func AuthInfoFromPeer(p *peer.Peer) (AuthInfo, error) {
+	s2aAuthInfo, ok := p.AuthInfo.(AuthInfo)
+	if !ok {
+		return nil, errors.New("no S2AAuthInfo found in Peer")
+	}
+	return s2aAuthInfo, nil
+}
+
+// AuthInfoFromContext extracts the authinfo.S2AAuthInfo object from the given
+// context, if it exists. This API should be used by gRPC server RPC handlers
+// to get information about the peer. On the client-side, use the grpc.Peer()
+// CallOption and the AuthInfoFromPeer function.
+func AuthInfoFromContext(ctx context.Context) (AuthInfo, error) {
+	p, ok := peer.FromContext(ctx)
+	if !ok {
+		return nil, errors.New("no Peer found in Context")
+	}
+	return AuthInfoFromPeer(p)
+}

+ 34 - 0
vendor/github.com/google/s2a-go/stream/s2a_stream.go

@@ -0,0 +1,34 @@
+/*
+ *
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package stream provides an interface for bidirectional streaming to the S2A server.
+package stream
+
+import (
+	s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto"
+)
+
+// S2AStream defines the operation for communicating with the S2A server over a bidirectional stream.
+type S2AStream interface {
+	// Send sends the message to the S2A server.
+	Send(*s2av2pb.SessionReq) error
+	// Recv receives the message from the S2A server.
+	Recv() (*s2av2pb.SessionResp, error)
+	// Closes the channel to the S2A server.
+	CloseSend() error
+}

+ 24 - 0
vendor/github.com/google/s2a-go/testdata/client_cert.pem

@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID8TCCAtmgAwIBAgIUKXNlBRVe6UepjQUijIFPZBd/4qYwDQYJKoZIhvcNAQEL
+BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2
+YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE
+AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN
+MjIwNTMxMjAwMzE1WhcNNDIwNTI2MjAwMzE1WjCBhzELMAkGA1UEBhMCVVMxCzAJ
+BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx
+ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ
+KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAOOFuIucH7XXfohGxKd3uR/ihUA/LdduR9I8kfpUEbq5BOt8xZe5/Yn9
+a1ozEHVW6cOAbHbnwAR8tkSgZ/t42QIA2k77HWU1Jh2xiEIsJivo3imm4/kZWuR0
+OqPh7MhzxpR/hvNwpI5mJsAVBWFMa5KtecFZLnyZtwHylrRN1QXzuLrOxuKFufK3
+RKbTABScn5RbZL976H/jgfSeXrbt242NrIoBnVe6fRbekbq2DQ6zFArbQMUgHjHK
+P0UqBgdr1QmHfi9KytFyx9BTP3gXWnWIu+bY7/v7qKJMHFwGETo+dCLWYevJL316
+HnLfhApDMfP8U+Yv/y1N/YvgaSOSlEcCAwEAAaNTMFEwHQYDVR0OBBYEFKhAU4nu
+0h/lrnggbIGvx4ej0WklMB8GA1UdIwQYMBaAFKhAU4nu0h/lrnggbIGvx4ej0Wkl
+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAE/6NghzQ5fu6yR6
+EHKbj/YMrFdT7aGn5n2sAf7wJ33LIhiFHkpWBsVlm7rDtZtwhe891ZK/P60anlg9
+/P0Ua53tSRVRmCvTnEbXWOVMN4is6MsR7BlmzUxl4AtIn7jbeifEwRL7B4xDYmdA
+QrQnsqoz45dLgS5xK4WDqXATP09Q91xQDuhud/b+A4jrvgwFASmL7rMIZbp4f1JQ
+nlnl/9VoTBQBvJiWkDUtQDMpRLtauddEkv4AGz75p5IspXWD6cOemuh2iQec11xD
+X20rs2WZbAcAiUa3nmy8OKYw435vmpj8gp39WYbX/Yx9TymrFFbVY92wYn+quTco
+pKklVz0=
+-----END CERTIFICATE-----

+ 27 - 0
vendor/github.com/google/s2a-go/testdata/client_key.pem

@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEA44W4i5wftdd+iEbEp3e5H+KFQD8t125H0jyR+lQRurkE63zF
+l7n9if1rWjMQdVbpw4BsdufABHy2RKBn+3jZAgDaTvsdZTUmHbGIQiwmK+jeKabj
++Rla5HQ6o+HsyHPGlH+G83CkjmYmwBUFYUxrkq15wVkufJm3AfKWtE3VBfO4us7G
+4oW58rdEptMAFJyflFtkv3vof+OB9J5etu3bjY2sigGdV7p9Ft6RurYNDrMUCttA
+xSAeMco/RSoGB2vVCYd+L0rK0XLH0FM/eBdadYi75tjv+/uookwcXAYROj50ItZh
+68kvfXoect+ECkMx8/xT5i//LU39i+BpI5KURwIDAQABAoIBABgyjo/6iLzUMFbZ
+/+w3pW6orrdIgN2akvTfED9pVYFgUA+jc3hRhY95bkNnjuaL2cy7Cc4Tk65mfRQL
+Y0OxdJLr+EvSFSxAXM9npDA1ddHRsF8JqtFBSxNk8R+g1Yf0GDiO35Fgd3/ViWWA
+VtQkRoSRApP3oiQKTRZd8H04keFR+PvmDk/Lq11l3Kc24A1PevKIPX1oI990ggw9
+9i4uSV+cnuMxmcI9xxJtgwdDFdjr39l2arLOHr4s6LGoV2IOdXHNlv5xRqWUZ0FH
+MDHowkLgwDrdSTnNeaVNkce14Gqx+bd4hNaLCdKXMpedBTEmrut3f3hdV1kKjaKt
+aqRYr8ECgYEA/YDGZY2jvFoHHBywlqmEMFrrCvQGH51m5R1Ntpkzr+Rh3YCmrpvq
+xgwJXING0PUw3dz+xrH5lJICrfNE5Kt3fPu1rAEy+13mYsNowghtUq2Rtu0Hsjjx
+2E3Bf8vEB6RNBMmGkUpTTIAroGF5tpJoRvfnWax+k4pFdrKYFtyZdNcCgYEA5cNv
+EPltvOobjTXlUmtVP3n27KZN2aXexTcagLzRxE9CV4cYySENl3KuOMmccaZpIl6z
+aHk6BT4X+M0LqElNUczrInfVqI+SGAFLGy7W6CJaqSr6cpyFUP/fosKpm6wKGgLq
+udHfpvz5rckhKd8kJxFLvhGOK9yN5qpzih0gfhECgYAJfwRvk3G5wYmYpP58dlcs
+VIuPenqsPoI3PPTHTU/hW+XKnWIhElgmGRdUrto9Q6IT/Y5RtSMLTLjq+Tzwb/fm
+56rziYv2XJsfwgAvnI8z1Kqrto9ePsHYf3krJ1/thVsZPc9bq/QY3ohD1sLvcuaT
+GgBBnLOVJU3a12/ZE2RwOwKBgF0csWMAoj8/5IB6if+3ral2xOGsl7oPZVMo/J2V
+Z7EVqb4M6rd/pKFugTpUQgkwtkSOekhpcGD1hAN5HTNK2YG/+L5UMAsKe9sskwJm
+HgOfAHy0BSDzW3ey6i9skg2bT9Cww+0gJ3Hl7U1HSCBO5LjMYpSZSrNtwzfqdb5Q
+BX3xAoGARZdR28Ej3+/+0+fz47Yu2h4z0EI/EbrudLOWY936jIeAVwHckI3+BuqH
+qR4poj1gfbnMxNuI9UzIXzjEmGewx9kDZ7IYnvloZKqoVQODO5GlKF2ja6IcMNlh
+GCNdD6PSAS6HcmalmWo9sj+1YMkrl+GJikKZqVBHrHNwMGAG67w=
+-----END RSA PRIVATE KEY-----

+ 24 - 0
vendor/github.com/google/s2a-go/testdata/server_cert.pem

@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID8TCCAtmgAwIBAgIUKCoDuLtiZXvhsBY2RoDm0ugizJ8wDQYJKoZIhvcNAQEL
+BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2
+YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE
+AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN
+MjIwNTMxMjAwODI1WhcNNDIwNTI2MjAwODI1WjCBhzELMAkGA1UEBhMCVVMxCzAJ
+BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx
+ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ
+KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAKK1++PXQ+M3hjYH/v0K4UEYl5ljzpNM1i52eQM+gFooojT87PDSaphT
+fs0PXy/PTAjHBEvPhWpOpmQXfJNYzjwcCvg66hbqkv++/VTZiFLAsHagzkEz+FRJ
+qT5Eq7G5FLyw1izX1uxyPN7tAEWEEg7eqsiaXD3Cq8+TYN9cjirPeF7RZF8yFCYE
+xqvbo+Yc6RL6xw19iXVTfctRgQe581KQuIY5/LXo3dWDEilFdsADAe8XAEcO64es
+Ow0g1UvXLnpXSE151kXBFb3sKH/ZjCecDYMCIMEb4sWLSblkSxJ5sNSmXIG4wtr2
+Qnii7CXZgnVYraQE/Jyh+NMQANuoSdMCAwEAAaNTMFEwHQYDVR0OBBYEFAyQQQuM
+ab+YUQqjK8dVVOoHVFmXMB8GA1UdIwQYMBaAFAyQQQuMab+YUQqjK8dVVOoHVFmX
+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADj0vQ6ykWhicoqR
+e6VZMwlEJV7/DSvWWKBd9MUjfKye0A4565ya5lmnzP3DiD3nqGe3miqmLsXKDs+X
+POqlPXTWIamP7D4MJ32XtSLwZB4ru+I+Ao/P/VngPepoRPQoBnzHe7jww0rokqxl
+AZERjlbTUwUAy/BPWPSzSJZ2j0tcs6ZLDNyYzpK4ao8R9/1VmQ92Tcp3feJs1QTg
+odRQc3om/AkWOwsll+oyX0UbJeHkFHiLanUPXbdh+/BkSvZJ8ynL+feSDdaurPe+
+PSfnqLtQft9/neecGRdEaQzzzSFVQUVQzTdK1Q7hA7b55b2HvIa3ktDiks+sJsYN
+Dhm6uZM=
+-----END CERTIFICATE-----

+ 27 - 0
vendor/github.com/google/s2a-go/testdata/server_key.pem

@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAorX749dD4zeGNgf+/QrhQRiXmWPOk0zWLnZ5Az6AWiiiNPzs
+8NJqmFN+zQ9fL89MCMcES8+Fak6mZBd8k1jOPBwK+DrqFuqS/779VNmIUsCwdqDO
+QTP4VEmpPkSrsbkUvLDWLNfW7HI83u0ARYQSDt6qyJpcPcKrz5Ng31yOKs94XtFk
+XzIUJgTGq9uj5hzpEvrHDX2JdVN9y1GBB7nzUpC4hjn8tejd1YMSKUV2wAMB7xcA
+Rw7rh6w7DSDVS9cueldITXnWRcEVvewof9mMJ5wNgwIgwRvixYtJuWRLEnmw1KZc
+gbjC2vZCeKLsJdmCdVitpAT8nKH40xAA26hJ0wIDAQABAoIBACaNR+lsD8G+XiZf
+LqN1+HkcAo9tfnyYMAdCOtnx7SdviT9Uzi8hK/B7mAeuJLeHPlS2EuaDfPD7QaFl
+jza6S+MiIdc+3kgfvESsVAnOoOY6kZUJ9NSuI6CU82y1iJjLaYZrv9NQMLRFPPb0
+4KOX709mosB1EnXvshW0rbc+jtDFhrm1SxMt+k9TuzmMxjbOeW4LOLXPgU8X1T3Q
+Xy0hMZZtcgBs9wFIo8yCtmOixax9pnFE8rRltgDxTodn9LLdz1FieyntNgDksZ0P
+nt4kV7Mqly7ELaea+Foaj244mKsesic2e3GhAlMRLun/VSunSf7mOCxfpITB8dp1
+drDhOYECgYEA19151dVxRcviuovN6Dar+QszMTnU8pDJ8BjLFjXjP/hNBBwMTHDE
+duMuWk2qnwZqMooI/shxrF/ufmTgS0CFrh2+ANBZu27vWConJNXcyNtdigI4wt50
+L0Y2qcZn2mg67qFXHwoR3QNwrwnPwEjRXA09at9CSRZzcwDQ0ETXhYsCgYEAwPaG
+06QdK8Zyly7TTzZJwxzv9uGiqzodmGtX6NEKjgij2JaCxHpukqZBJoqa0jKeK1cm
+eNVkOvT5ff9TMzarSHQLr3pZen2/oVLb5gaFkbcJt/klv9Fd+ZRilHY3i6QwS6pD
+uMiPOWS4DrLHDRVoVlAZTDjT1RVwwTs+P2NhJdkCgYEAsriXysbxBYyMp05gqEW7
+lHIFbFgpSrs9th+Q5U6wW6JEgYaHWDJ1NslY80MiZI93FWjbkbZ7BvBWESeL3EIL
+a+EMErht0pVCbIhZ6FF4foPAqia0wAJVx14mm+G80kNBp5jE/NnleEsE3KcO7nBb
+hg8gLn+x7bk81JZ0TDrzBYkCgYEAuQKluv47SeF3tSScTfKLPpvcKCWmxe1uutkQ
+7JShPhVioyOMNb39jnYBOWbjkm4d4QgqRuiytSR0oi3QI+Ziy5EYMyNn713qAk9j
+r2TJZDDPDKnBW+zt4YI4EohWMXk3JRUW4XDKggjjwJQA7bZ812TtHHvP/xoThfG7
+eSNb3eECgYBw6ssgCtMrdvQiEmjKVX/9yI38mvC2kSGyzbrQnGUfgqRGomRpeZuD
+B5E3kysA4td5pT5lvcLgSW0TbOz+YbiriXjwOihPIelCvc9gE2eOUI71/byUWPFz
+7u5F/xQ4NaGr5suLF+lBC6h7pSbM4El9lIHQAQadpuEdzHqrw+hs3g==
+-----END RSA PRIVATE KEY-----

+ 1 - 1
vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json

@@ -1,3 +1,3 @@
 {
-    "v2": "2.7.1"
+    "v2": "2.11.0"
 }

+ 45 - 0
vendor/github.com/googleapis/gax-go/v2/CHANGES.md

@@ -1,5 +1,50 @@
 # Changelog
 
+## [2.11.0](https://github.com/googleapis/gax-go/compare/v2.10.0...v2.11.0) (2023-06-13)
+
+
+### Features
+
+* **v2:** add GoVersion package variable ([#283](https://github.com/googleapis/gax-go/issues/283)) ([26553cc](https://github.com/googleapis/gax-go/commit/26553ccadb4016b189881f52e6c253b68bb3e3d5))
+
+
+### Bug Fixes
+
+* **v2:** handle space in non-devel go version ([#288](https://github.com/googleapis/gax-go/issues/288)) ([fd7bca0](https://github.com/googleapis/gax-go/commit/fd7bca029a1c5e63def8f0a5fd1ec3f725d92f75))
+
+## [2.10.0](https://github.com/googleapis/gax-go/compare/v2.9.1...v2.10.0) (2023-05-30)
+
+
+### Features
+
+* update dependencies ([#280](https://github.com/googleapis/gax-go/issues/280)) ([4514281](https://github.com/googleapis/gax-go/commit/4514281058590f3637c36bfd49baa65c4d3cfb21))
+
+## [2.9.1](https://github.com/googleapis/gax-go/compare/v2.9.0...v2.9.1) (2023-05-23)
+
+
+### Bug Fixes
+
+* **v2:** drop cloud lro test dep ([#276](https://github.com/googleapis/gax-go/issues/276)) ([c67eeba](https://github.com/googleapis/gax-go/commit/c67eeba0f10a3294b1d93c1b8fbe40211a55ae5f)), refs [#270](https://github.com/googleapis/gax-go/issues/270)
+
+## [2.9.0](https://github.com/googleapis/gax-go/compare/v2.8.0...v2.9.0) (2023-05-22)
+
+
+### Features
+
+* **apierror:** add method to return HTTP status code conditionally ([#274](https://github.com/googleapis/gax-go/issues/274)) ([5874431](https://github.com/googleapis/gax-go/commit/587443169acd10f7f86d1989dc8aaf189e645e98)), refs [#229](https://github.com/googleapis/gax-go/issues/229)
+
+
+### Documentation
+
+* add ref to usage with clients ([#272](https://github.com/googleapis/gax-go/issues/272)) ([ea4d72d](https://github.com/googleapis/gax-go/commit/ea4d72d514beba4de450868b5fb028601a29164e)), refs [#228](https://github.com/googleapis/gax-go/issues/228)
+
+## [2.8.0](https://github.com/googleapis/gax-go/compare/v2.7.1...v2.8.0) (2023-03-15)
+
+
+### Features
+
+* **v2:** add WithTimeout option ([#259](https://github.com/googleapis/gax-go/issues/259)) ([9a8da43](https://github.com/googleapis/gax-go/commit/9a8da43693002448b1e8758023699387481866d1))
+
 ## [2.7.1](https://github.com/googleapis/gax-go/compare/v2.7.0...v2.7.1) (2023-03-06)
 
 

+ 14 - 0
vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go

@@ -29,6 +29,10 @@
 
 // Package apierror implements a wrapper error for parsing error details from
 // API calls. Both HTTP & gRPC status errors are supported.
+//
+// For examples of how to use [APIError] with client libraries please reference
+// [Inspecting errors](https://pkg.go.dev/cloud.google.com/go#hdr-Inspecting_errors)
+// in the client library documentation.
 package apierror
 
 import (
@@ -345,3 +349,13 @@ func parseHTTPDetails(gae *googleapi.Error) ErrDetails {
 
 	return parseDetails(details)
 }
+
+// HTTPCode returns the underlying HTTP response status code. This method returns
+// `-1` if the underlying error is a [google.golang.org/grpc/status.Status]. To
+// check gRPC error codes use [google.golang.org/grpc/status.Code].
+func (a *APIError) HTTPCode() int {
+	if a.httpErr == nil {
+		return -1
+	}
+	return a.httpErr.Code
+}

+ 21 - 0
vendor/github.com/googleapis/gax-go/v2/call_option.go

@@ -218,6 +218,14 @@ func (p pathOpt) Resolve(s *CallSettings) {
 	s.Path = p.p
 }
 
+type timeoutOpt struct {
+	t time.Duration
+}
+
+func (t timeoutOpt) Resolve(s *CallSettings) {
+	s.timeout = t.t
+}
+
 // WithPath applies a Path override to the HTTP-based APICall.
 //
 // This is for internal use only.
@@ -230,6 +238,15 @@ func WithGRPCOptions(opt ...grpc.CallOption) CallOption {
 	return grpcOpt(append([]grpc.CallOption(nil), opt...))
 }
 
+// WithTimeout is a convenience option for setting a context.WithTimeout on the
+// singular context.Context used for **all** APICall attempts. Calculated from
+// the start of the first APICall attempt.
+// If the context.Context provided to Invoke already has a Deadline set, that
+// will always be respected over the deadline calculated using this option.
+func WithTimeout(t time.Duration) CallOption {
+	return &timeoutOpt{t: t}
+}
+
 // CallSettings allow fine-grained control over how calls are made.
 type CallSettings struct {
 	// Retry returns a Retryer to be used to control retry logic of a method call.
@@ -241,4 +258,8 @@ type CallSettings struct {
 
 	// Path is an HTTP override for an APICall.
 	Path string
+
+	// Timeout defines the amount of time that Invoke has to complete.
+	// Unexported so it cannot be changed by the code in an APICall.
+	timeout time.Duration
 }

+ 67 - 1
vendor/github.com/googleapis/gax-go/v2/header.go

@@ -29,7 +29,73 @@
 
 package gax
 
-import "bytes"
+import (
+	"bytes"
+	"runtime"
+	"strings"
+	"unicode"
+)
+
+var (
+	// GoVersion is a header-safe representation of the current runtime
+	// environment's Go version. This is for GAX consumers that need to
+	// report the Go runtime version in API calls.
+	GoVersion string
+	// version is a package internal global variable for testing purposes.
+	version = runtime.Version
+)
+
+// versionUnknown is only used when the runtime version cannot be determined.
+const versionUnknown = "UNKNOWN"
+
+func init() {
+	GoVersion = goVersion()
+}
+
+// goVersion returns a Go runtime version derived from the runtime environment
+// that is modified to be suitable for reporting in a header, meaning it has no
+// whitespace. If it is unable to determine the Go runtime version, it returns
+// versionUnknown.
+func goVersion() string {
+	const develPrefix = "devel +"
+
+	s := version()
+	if strings.HasPrefix(s, develPrefix) {
+		s = s[len(develPrefix):]
+		if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
+			s = s[:p]
+		}
+		return s
+	} else if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
+		s = s[:p]
+	}
+
+	notSemverRune := func(r rune) bool {
+		return !strings.ContainsRune("0123456789.", r)
+	}
+
+	if strings.HasPrefix(s, "go1") {
+		s = s[2:]
+		var prerelease string
+		if p := strings.IndexFunc(s, notSemverRune); p >= 0 {
+			s, prerelease = s[:p], s[p:]
+		}
+		if strings.HasSuffix(s, ".") {
+			s += "0"
+		} else if strings.Count(s, ".") < 2 {
+			s += ".0"
+		}
+		if prerelease != "" {
+			// Some release candidates already have a dash in them.
+			if !strings.HasPrefix(prerelease, "-") {
+				prerelease = "-" + prerelease
+			}
+			s += prerelease
+		}
+		return s
+	}
+	return "UNKNOWN"
+}
 
 // XGoogHeader is for use by the Google Cloud Libraries only.
 //

+ 1 - 1
vendor/github.com/googleapis/gax-go/v2/internal/version.go

@@ -30,4 +30,4 @@
 package internal
 
 // Version is the current tagged release of the library.
-const Version = "2.7.1"
+const Version = "2.11.0"

+ 10 - 0
vendor/github.com/googleapis/gax-go/v2/invoke.go

@@ -68,6 +68,16 @@ type sleeper func(ctx context.Context, d time.Duration) error
 // invoke implements Invoke, taking an additional sleeper argument for testing.
 func invoke(ctx context.Context, call APICall, settings CallSettings, sp sleeper) error {
 	var retryer Retryer
+
+	// Only use the value provided via WithTimeout if the context doesn't
+	// already have a deadline. This is important for backwards compatibility if
+	// the user already set a deadline on the context given to Invoke.
+	if _, ok := ctx.Deadline(); !ok && settings.timeout != 0 {
+		c, cc := context.WithTimeout(ctx, settings.timeout)
+		defer cc()
+		ctx = c
+	}
+
 	for {
 		err := call(ctx, settings)
 		if err == nil {

+ 98 - 0
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go

@@ -0,0 +1,98 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package chacha20poly1305 implements the ChaCha20-Poly1305 AEAD and its
+// extended nonce variant XChaCha20-Poly1305, as specified in RFC 8439 and
+// draft-irtf-cfrg-xchacha-01.
+package chacha20poly1305 // import "golang.org/x/crypto/chacha20poly1305"
+
+import (
+	"crypto/cipher"
+	"errors"
+)
+
+const (
+	// KeySize is the size of the key used by this AEAD, in bytes.
+	KeySize = 32
+
+	// NonceSize is the size of the nonce used with the standard variant of this
+	// AEAD, in bytes.
+	//
+	// Note that this is too short to be safely generated at random if the same
+	// key is reused more than 2³² times.
+	NonceSize = 12
+
+	// NonceSizeX is the size of the nonce used with the XChaCha20-Poly1305
+	// variant of this AEAD, in bytes.
+	NonceSizeX = 24
+
+	// Overhead is the size of the Poly1305 authentication tag, and the
+	// difference between a ciphertext length and its plaintext.
+	Overhead = 16
+)
+
+type chacha20poly1305 struct {
+	key [KeySize]byte
+}
+
+// New returns a ChaCha20-Poly1305 AEAD that uses the given 256-bit key.
+func New(key []byte) (cipher.AEAD, error) {
+	if len(key) != KeySize {
+		return nil, errors.New("chacha20poly1305: bad key length")
+	}
+	ret := new(chacha20poly1305)
+	copy(ret.key[:], key)
+	return ret, nil
+}
+
+func (c *chacha20poly1305) NonceSize() int {
+	return NonceSize
+}
+
+func (c *chacha20poly1305) Overhead() int {
+	return Overhead
+}
+
+func (c *chacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
+	if len(nonce) != NonceSize {
+		panic("chacha20poly1305: bad nonce length passed to Seal")
+	}
+
+	if uint64(len(plaintext)) > (1<<38)-64 {
+		panic("chacha20poly1305: plaintext too large")
+	}
+
+	return c.seal(dst, nonce, plaintext, additionalData)
+}
+
+var errOpen = errors.New("chacha20poly1305: message authentication failed")
+
+func (c *chacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+	if len(nonce) != NonceSize {
+		panic("chacha20poly1305: bad nonce length passed to Open")
+	}
+	if len(ciphertext) < 16 {
+		return nil, errOpen
+	}
+	if uint64(len(ciphertext)) > (1<<38)-48 {
+		panic("chacha20poly1305: ciphertext too large")
+	}
+
+	return c.open(dst, nonce, ciphertext, additionalData)
+}
+
+// sliceForAppend takes a slice and a requested number of bytes. It returns a
+// slice with the contents of the given slice followed by that many bytes and a
+// second slice that aliases into it and contains only the extra bytes. If the
+// original slice has sufficient capacity then no allocation is performed.
+func sliceForAppend(in []byte, n int) (head, tail []byte) {
+	if total := len(in) + n; cap(in) >= total {
+		head = in[:total]
+	} else {
+		head = make([]byte, total)
+		copy(head, in)
+	}
+	tail = head[len(in):]
+	return
+}

+ 87 - 0
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go

@@ -0,0 +1,87 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc && !purego
+// +build gc,!purego
+
+package chacha20poly1305
+
+import (
+	"encoding/binary"
+
+	"golang.org/x/crypto/internal/alias"
+	"golang.org/x/sys/cpu"
+)
+
+//go:noescape
+func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool
+
+//go:noescape
+func chacha20Poly1305Seal(dst []byte, key []uint32, src, ad []byte)
+
+var (
+	useAVX2 = cpu.X86.HasAVX2 && cpu.X86.HasBMI2
+)
+
+// setupState writes a ChaCha20 input matrix to state. See
+// https://tools.ietf.org/html/rfc7539#section-2.3.
+func setupState(state *[16]uint32, key *[32]byte, nonce []byte) {
+	state[0] = 0x61707865
+	state[1] = 0x3320646e
+	state[2] = 0x79622d32
+	state[3] = 0x6b206574
+
+	state[4] = binary.LittleEndian.Uint32(key[0:4])
+	state[5] = binary.LittleEndian.Uint32(key[4:8])
+	state[6] = binary.LittleEndian.Uint32(key[8:12])
+	state[7] = binary.LittleEndian.Uint32(key[12:16])
+	state[8] = binary.LittleEndian.Uint32(key[16:20])
+	state[9] = binary.LittleEndian.Uint32(key[20:24])
+	state[10] = binary.LittleEndian.Uint32(key[24:28])
+	state[11] = binary.LittleEndian.Uint32(key[28:32])
+
+	state[12] = 0
+	state[13] = binary.LittleEndian.Uint32(nonce[0:4])
+	state[14] = binary.LittleEndian.Uint32(nonce[4:8])
+	state[15] = binary.LittleEndian.Uint32(nonce[8:12])
+}
+
+func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte {
+	if !cpu.X86.HasSSSE3 {
+		return c.sealGeneric(dst, nonce, plaintext, additionalData)
+	}
+
+	var state [16]uint32
+	setupState(&state, &c.key, nonce)
+
+	ret, out := sliceForAppend(dst, len(plaintext)+16)
+	if alias.InexactOverlap(out, plaintext) {
+		panic("chacha20poly1305: invalid buffer overlap")
+	}
+	chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData)
+	return ret
+}
+
+func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+	if !cpu.X86.HasSSSE3 {
+		return c.openGeneric(dst, nonce, ciphertext, additionalData)
+	}
+
+	var state [16]uint32
+	setupState(&state, &c.key, nonce)
+
+	ciphertext = ciphertext[:len(ciphertext)-16]
+	ret, out := sliceForAppend(dst, len(ciphertext))
+	if alias.InexactOverlap(out, ciphertext) {
+		panic("chacha20poly1305: invalid buffer overlap")
+	}
+	if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) {
+		for i := range out {
+			out[i] = 0
+		}
+		return nil, errOpen
+	}
+
+	return ret, nil
+}

+ 2696 - 0
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s

@@ -0,0 +1,2696 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file was originally from https://golang.org/cl/24717 by Vlad Krasnov of CloudFlare.
+
+//go:build gc && !purego
+// +build gc,!purego
+
+#include "textflag.h"
+// General register allocation
+#define oup DI
+#define inp SI
+#define inl BX
+#define adp CX // free to reuse, after we hash the additional data
+#define keyp R8 // free to reuse, when we copy the key to stack
+#define itr2 R9 // general iterator
+#define itr1 CX // general iterator
+#define acc0 R10
+#define acc1 R11
+#define acc2 R12
+#define t0 R13
+#define t1 R14
+#define t2 R15
+#define t3 R8
+// Register and stack allocation for the SSE code
+#define rStore (0*16)(BP)
+#define sStore (1*16)(BP)
+#define state1Store (2*16)(BP)
+#define state2Store (3*16)(BP)
+#define tmpStore (4*16)(BP)
+#define ctr0Store (5*16)(BP)
+#define ctr1Store (6*16)(BP)
+#define ctr2Store (7*16)(BP)
+#define ctr3Store (8*16)(BP)
+#define A0 X0
+#define A1 X1
+#define A2 X2
+#define B0 X3
+#define B1 X4
+#define B2 X5
+#define C0 X6
+#define C1 X7
+#define C2 X8
+#define D0 X9
+#define D1 X10
+#define D2 X11
+#define T0 X12
+#define T1 X13
+#define T2 X14
+#define T3 X15
+#define A3 T0
+#define B3 T1
+#define C3 T2
+#define D3 T3
+// Register and stack allocation for the AVX2 code
+#define rsStoreAVX2 (0*32)(BP)
+#define state1StoreAVX2 (1*32)(BP)
+#define state2StoreAVX2 (2*32)(BP)
+#define ctr0StoreAVX2 (3*32)(BP)
+#define ctr1StoreAVX2 (4*32)(BP)
+#define ctr2StoreAVX2 (5*32)(BP)
+#define ctr3StoreAVX2 (6*32)(BP)
+#define tmpStoreAVX2 (7*32)(BP) // 256 bytes on stack
+#define AA0 Y0
+#define AA1 Y5
+#define AA2 Y6
+#define AA3 Y7
+#define BB0 Y14
+#define BB1 Y9
+#define BB2 Y10
+#define BB3 Y11
+#define CC0 Y12
+#define CC1 Y13
+#define CC2 Y8
+#define CC3 Y15
+#define DD0 Y4
+#define DD1 Y1
+#define DD2 Y2
+#define DD3 Y3
+#define TT0 DD3
+#define TT1 AA3
+#define TT2 BB3
+#define TT3 CC3
+// ChaCha20 constants
+DATA ·chacha20Constants<>+0x00(SB)/4, $0x61707865
+DATA ·chacha20Constants<>+0x04(SB)/4, $0x3320646e
+DATA ·chacha20Constants<>+0x08(SB)/4, $0x79622d32
+DATA ·chacha20Constants<>+0x0c(SB)/4, $0x6b206574
+DATA ·chacha20Constants<>+0x10(SB)/4, $0x61707865
+DATA ·chacha20Constants<>+0x14(SB)/4, $0x3320646e
+DATA ·chacha20Constants<>+0x18(SB)/4, $0x79622d32
+DATA ·chacha20Constants<>+0x1c(SB)/4, $0x6b206574
+// <<< 16 with PSHUFB
+DATA ·rol16<>+0x00(SB)/8, $0x0504070601000302
+DATA ·rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A
+DATA ·rol16<>+0x10(SB)/8, $0x0504070601000302
+DATA ·rol16<>+0x18(SB)/8, $0x0D0C0F0E09080B0A
+// <<< 8 with PSHUFB
+DATA ·rol8<>+0x00(SB)/8, $0x0605040702010003
+DATA ·rol8<>+0x08(SB)/8, $0x0E0D0C0F0A09080B
+DATA ·rol8<>+0x10(SB)/8, $0x0605040702010003
+DATA ·rol8<>+0x18(SB)/8, $0x0E0D0C0F0A09080B
+
+DATA ·avx2InitMask<>+0x00(SB)/8, $0x0
+DATA ·avx2InitMask<>+0x08(SB)/8, $0x0
+DATA ·avx2InitMask<>+0x10(SB)/8, $0x1
+DATA ·avx2InitMask<>+0x18(SB)/8, $0x0
+
+DATA ·avx2IncMask<>+0x00(SB)/8, $0x2
+DATA ·avx2IncMask<>+0x08(SB)/8, $0x0
+DATA ·avx2IncMask<>+0x10(SB)/8, $0x2
+DATA ·avx2IncMask<>+0x18(SB)/8, $0x0
+// Poly1305 key clamp
+DATA ·polyClampMask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
+DATA ·polyClampMask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
+DATA ·polyClampMask<>+0x10(SB)/8, $0xFFFFFFFFFFFFFFFF
+DATA ·polyClampMask<>+0x18(SB)/8, $0xFFFFFFFFFFFFFFFF
+
+DATA ·sseIncMask<>+0x00(SB)/8, $0x1
+DATA ·sseIncMask<>+0x08(SB)/8, $0x0
+// To load/store the last < 16 bytes in a buffer
+DATA ·andMask<>+0x00(SB)/8, $0x00000000000000ff
+DATA ·andMask<>+0x08(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x10(SB)/8, $0x000000000000ffff
+DATA ·andMask<>+0x18(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x20(SB)/8, $0x0000000000ffffff
+DATA ·andMask<>+0x28(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x30(SB)/8, $0x00000000ffffffff
+DATA ·andMask<>+0x38(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x40(SB)/8, $0x000000ffffffffff
+DATA ·andMask<>+0x48(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x50(SB)/8, $0x0000ffffffffffff
+DATA ·andMask<>+0x58(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x60(SB)/8, $0x00ffffffffffffff
+DATA ·andMask<>+0x68(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x70(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0x78(SB)/8, $0x0000000000000000
+DATA ·andMask<>+0x80(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0x88(SB)/8, $0x00000000000000ff
+DATA ·andMask<>+0x90(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0x98(SB)/8, $0x000000000000ffff
+DATA ·andMask<>+0xa0(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0xa8(SB)/8, $0x0000000000ffffff
+DATA ·andMask<>+0xb0(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0xb8(SB)/8, $0x00000000ffffffff
+DATA ·andMask<>+0xc0(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0xc8(SB)/8, $0x000000ffffffffff
+DATA ·andMask<>+0xd0(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0xd8(SB)/8, $0x0000ffffffffffff
+DATA ·andMask<>+0xe0(SB)/8, $0xffffffffffffffff
+DATA ·andMask<>+0xe8(SB)/8, $0x00ffffffffffffff
+
+GLOBL ·chacha20Constants<>(SB), (NOPTR+RODATA), $32
+GLOBL ·rol16<>(SB), (NOPTR+RODATA), $32
+GLOBL ·rol8<>(SB), (NOPTR+RODATA), $32
+GLOBL ·sseIncMask<>(SB), (NOPTR+RODATA), $16
+GLOBL ·avx2IncMask<>(SB), (NOPTR+RODATA), $32
+GLOBL ·avx2InitMask<>(SB), (NOPTR+RODATA), $32
+GLOBL ·polyClampMask<>(SB), (NOPTR+RODATA), $32
+GLOBL ·andMask<>(SB), (NOPTR+RODATA), $240
+// No PALIGNR in Go ASM yet (but VPALIGNR is present).
+#define shiftB0Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x04 // PALIGNR $4, X3, X3
+#define shiftB1Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xe4; BYTE $0x04 // PALIGNR $4, X4, X4
+#define shiftB2Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x04 // PALIGNR $4, X5, X5
+#define shiftB3Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x04 // PALIGNR $4, X13, X13
+#define shiftC0Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xf6; BYTE $0x08 // PALIGNR $8, X6, X6
+#define shiftC1Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xff; BYTE $0x08 // PALIGNR $8, X7, X7
+#define shiftC2Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xc0; BYTE $0x08 // PALIGNR $8, X8, X8
+#define shiftC3Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xf6; BYTE $0x08 // PALIGNR $8, X14, X14
+#define shiftD0Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xc9; BYTE $0x0c // PALIGNR $12, X9, X9
+#define shiftD1Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xd2; BYTE $0x0c // PALIGNR $12, X10, X10
+#define shiftD2Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x0c // PALIGNR $12, X11, X11
+#define shiftD3Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xff; BYTE $0x0c // PALIGNR $12, X15, X15
+#define shiftB0Right BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x0c // PALIGNR $12, X3, X3
+#define shiftB1Right BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xe4; BYTE $0x0c // PALIGNR $12, X4, X4
+#define shiftB2Right BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x0c // PALIGNR $12, X5, X5
+#define shiftB3Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x0c // PALIGNR $12, X13, X13
+#define shiftC0Right shiftC0Left
+#define shiftC1Right shiftC1Left
+#define shiftC2Right shiftC2Left
+#define shiftC3Right shiftC3Left
+#define shiftD0Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xc9; BYTE $0x04 // PALIGNR $4, X9, X9
+#define shiftD1Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xd2; BYTE $0x04 // PALIGNR $4, X10, X10
+#define shiftD2Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x04 // PALIGNR $4, X11, X11
+#define shiftD3Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xff; BYTE $0x04 // PALIGNR $4, X15, X15
+// Some macros
+#define chachaQR(A, B, C, D, T) \
+	PADDD B, A; PXOR A, D; PSHUFB ·rol16<>(SB), D                            \
+	PADDD D, C; PXOR C, B; MOVO B, T; PSLLL $12, T; PSRLL $20, B; PXOR T, B \
+	PADDD B, A; PXOR A, D; PSHUFB ·rol8<>(SB), D                             \
+	PADDD D, C; PXOR C, B; MOVO B, T; PSLLL $7, T; PSRLL $25, B; PXOR T, B
+
+#define chachaQR_AVX2(A, B, C, D, T) \
+	VPADDD B, A, A; VPXOR A, D, D; VPSHUFB ·rol16<>(SB), D, D                         \
+	VPADDD D, C, C; VPXOR C, B, B; VPSLLD $12, B, T; VPSRLD $20, B, B; VPXOR T, B, B \
+	VPADDD B, A, A; VPXOR A, D, D; VPSHUFB ·rol8<>(SB), D, D                          \
+	VPADDD D, C, C; VPXOR C, B, B; VPSLLD $7, B, T; VPSRLD $25, B, B; VPXOR T, B, B
+
+#define polyAdd(S) ADDQ S, acc0; ADCQ 8+S, acc1; ADCQ $1, acc2
+#define polyMulStage1 MOVQ (0*8)(BP), AX; MOVQ AX, t2; MULQ acc0; MOVQ AX, t0; MOVQ DX, t1; MOVQ (0*8)(BP), AX; MULQ acc1; IMULQ acc2, t2; ADDQ AX, t1; ADCQ DX, t2
+#define polyMulStage2 MOVQ (1*8)(BP), AX; MOVQ AX, t3; MULQ acc0; ADDQ AX, t1; ADCQ $0, DX; MOVQ DX, acc0; MOVQ (1*8)(BP), AX; MULQ acc1; ADDQ AX, t2; ADCQ $0, DX
+#define polyMulStage3 IMULQ acc2, t3; ADDQ acc0, t2; ADCQ DX, t3
+#define polyMulReduceStage MOVQ t0, acc0; MOVQ t1, acc1; MOVQ t2, acc2; ANDQ $3, acc2; MOVQ t2, t0; ANDQ $-4, t0; MOVQ t3, t1; SHRQ $2, t3, t2; SHRQ $2, t3; ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $0, acc2; ADDQ t2, acc0; ADCQ t3, acc1; ADCQ $0, acc2
+
+#define polyMulStage1_AVX2 MOVQ (0*8)(BP), DX; MOVQ DX, t2; MULXQ acc0, t0, t1; IMULQ acc2, t2; MULXQ acc1, AX, DX; ADDQ AX, t1; ADCQ DX, t2
+#define polyMulStage2_AVX2 MOVQ (1*8)(BP), DX; MULXQ acc0, acc0, AX; ADDQ acc0, t1; MULXQ acc1, acc1, t3; ADCQ acc1, t2; ADCQ $0, t3
+#define polyMulStage3_AVX2 IMULQ acc2, DX; ADDQ AX, t2; ADCQ DX, t3
+
+#define polyMul polyMulStage1; polyMulStage2; polyMulStage3; polyMulReduceStage
+#define polyMulAVX2 polyMulStage1_AVX2; polyMulStage2_AVX2; polyMulStage3_AVX2; polyMulReduceStage
+// ----------------------------------------------------------------------------
+TEXT polyHashADInternal<>(SB), NOSPLIT, $0
+	// adp points to beginning of additional data
+	// itr2 holds ad length
+	XORQ acc0, acc0
+	XORQ acc1, acc1
+	XORQ acc2, acc2
+	CMPQ itr2, $13
+	JNE  hashADLoop
+
+openFastTLSAD:
+	// Special treatment for the TLS case of 13 bytes
+	MOVQ (adp), acc0
+	MOVQ 5(adp), acc1
+	SHRQ $24, acc1
+	MOVQ $1, acc2
+	polyMul
+	RET
+
+hashADLoop:
+	// Hash in 16 byte chunks
+	CMPQ itr2, $16
+	JB   hashADTail
+	polyAdd(0(adp))
+	LEAQ (1*16)(adp), adp
+	SUBQ $16, itr2
+	polyMul
+	JMP  hashADLoop
+
+hashADTail:
+	CMPQ itr2, $0
+	JE   hashADDone
+
+	// Hash last < 16 byte tail
+	XORQ t0, t0
+	XORQ t1, t1
+	XORQ t2, t2
+	ADDQ itr2, adp
+
+hashADTailLoop:
+	SHLQ $8, t0, t1
+	SHLQ $8, t0
+	MOVB -1(adp), t2
+	XORQ t2, t0
+	DECQ adp
+	DECQ itr2
+	JNE  hashADTailLoop
+
+hashADTailFinish:
+	ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2
+	polyMul
+
+	// Finished AD
+hashADDone:
+	RET
+
+// ----------------------------------------------------------------------------
+// func chacha20Poly1305Open(dst, key, src, ad []byte) bool
+TEXT ·chacha20Poly1305Open(SB), 0, $288-97
+	// For aligned stack access
+	MOVQ SP, BP
+	ADDQ $32, BP
+	ANDQ $-32, BP
+	MOVQ dst+0(FP), oup
+	MOVQ key+24(FP), keyp
+	MOVQ src+48(FP), inp
+	MOVQ src_len+56(FP), inl
+	MOVQ ad+72(FP), adp
+
+	// Check for AVX2 support
+	CMPB ·useAVX2(SB), $1
+	JE   chacha20Poly1305Open_AVX2
+
+	// Special optimization, for very short buffers
+	CMPQ inl, $128
+	JBE  openSSE128 // About 16% faster
+
+	// For long buffers, prepare the poly key first
+	MOVOU ·chacha20Constants<>(SB), A0
+	MOVOU (1*16)(keyp), B0
+	MOVOU (2*16)(keyp), C0
+	MOVOU (3*16)(keyp), D0
+	MOVO  D0, T1
+
+	// Store state on stack for future use
+	MOVO B0, state1Store
+	MOVO C0, state2Store
+	MOVO D0, ctr3Store
+	MOVQ $10, itr2
+
+openSSEPreparePolyKey:
+	chachaQR(A0, B0, C0, D0, T0)
+	shiftB0Left;  shiftC0Left; shiftD0Left
+	chachaQR(A0, B0, C0, D0, T0)
+	shiftB0Right; shiftC0Right; shiftD0Right
+	DECQ          itr2
+	JNE           openSSEPreparePolyKey
+
+	// A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded
+	PADDL ·chacha20Constants<>(SB), A0; PADDL state1Store, B0
+
+	// Clamp and store the key
+	PAND ·polyClampMask<>(SB), A0
+	MOVO A0, rStore; MOVO B0, sStore
+
+	// Hash AAD
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+
+openSSEMainLoop:
+	CMPQ inl, $256
+	JB   openSSEMainLoopDone
+
+	// Load state, increment counter blocks
+	MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0
+	MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1
+	MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2
+	MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3
+
+	// Store counters
+	MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store
+
+	// There are 10 ChaCha20 iterations of 2QR each, so for 6 iterations we hash 2 blocks, and for the remaining 4 only 1 block - for a total of 16
+	MOVQ $4, itr1
+	MOVQ inp, itr2
+
+openSSEInternalLoop:
+	MOVO          C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO          tmpStore, C3
+	MOVO          C1, tmpStore
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO          tmpStore, C1
+	polyAdd(0(itr2))
+	shiftB0Left;  shiftB1Left; shiftB2Left; shiftB3Left
+	shiftC0Left;  shiftC1Left; shiftC2Left; shiftC3Left
+	shiftD0Left;  shiftD1Left; shiftD2Left; shiftD3Left
+	polyMulStage1
+	polyMulStage2
+	LEAQ          (2*8)(itr2), itr2
+	MOVO          C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO          tmpStore, C3
+	MOVO          C1, tmpStore
+	polyMulStage3
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO          tmpStore, C1
+	polyMulReduceStage
+	shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right
+	shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right
+	shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right
+	DECQ          itr1
+	JGE           openSSEInternalLoop
+
+	polyAdd(0(itr2))
+	polyMul
+	LEAQ (2*8)(itr2), itr2
+
+	CMPQ itr1, $-6
+	JG   openSSEInternalLoop
+
+	// Add in the state
+	PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3
+	PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3
+	PADDD state2Store, C0; PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3
+	PADDD ctr0Store, D0; PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3
+
+	// Load - xor - store
+	MOVO  D3, tmpStore
+	MOVOU (0*16)(inp), D3; PXOR D3, A0; MOVOU A0, (0*16)(oup)
+	MOVOU (1*16)(inp), D3; PXOR D3, B0; MOVOU B0, (1*16)(oup)
+	MOVOU (2*16)(inp), D3; PXOR D3, C0; MOVOU C0, (2*16)(oup)
+	MOVOU (3*16)(inp), D3; PXOR D3, D0; MOVOU D0, (3*16)(oup)
+	MOVOU (4*16)(inp), D0; PXOR D0, A1; MOVOU A1, (4*16)(oup)
+	MOVOU (5*16)(inp), D0; PXOR D0, B1; MOVOU B1, (5*16)(oup)
+	MOVOU (6*16)(inp), D0; PXOR D0, C1; MOVOU C1, (6*16)(oup)
+	MOVOU (7*16)(inp), D0; PXOR D0, D1; MOVOU D1, (7*16)(oup)
+	MOVOU (8*16)(inp), D0; PXOR D0, A2; MOVOU A2, (8*16)(oup)
+	MOVOU (9*16)(inp), D0; PXOR D0, B2; MOVOU B2, (9*16)(oup)
+	MOVOU (10*16)(inp), D0; PXOR D0, C2; MOVOU C2, (10*16)(oup)
+	MOVOU (11*16)(inp), D0; PXOR D0, D2; MOVOU D2, (11*16)(oup)
+	MOVOU (12*16)(inp), D0; PXOR D0, A3; MOVOU A3, (12*16)(oup)
+	MOVOU (13*16)(inp), D0; PXOR D0, B3; MOVOU B3, (13*16)(oup)
+	MOVOU (14*16)(inp), D0; PXOR D0, C3; MOVOU C3, (14*16)(oup)
+	MOVOU (15*16)(inp), D0; PXOR tmpStore, D0; MOVOU D0, (15*16)(oup)
+	LEAQ  256(inp), inp
+	LEAQ  256(oup), oup
+	SUBQ  $256, inl
+	JMP   openSSEMainLoop
+
+openSSEMainLoopDone:
+	// Handle the various tail sizes efficiently
+	TESTQ inl, inl
+	JE    openSSEFinalize
+	CMPQ  inl, $64
+	JBE   openSSETail64
+	CMPQ  inl, $128
+	JBE   openSSETail128
+	CMPQ  inl, $192
+	JBE   openSSETail192
+	JMP   openSSETail256
+
+openSSEFinalize:
+	// Hash in the PT, AAD lengths
+	ADDQ ad_len+80(FP), acc0; ADCQ src_len+56(FP), acc1; ADCQ $1, acc2
+	polyMul
+
+	// Final reduce
+	MOVQ    acc0, t0
+	MOVQ    acc1, t1
+	MOVQ    acc2, t2
+	SUBQ    $-5, acc0
+	SBBQ    $-1, acc1
+	SBBQ    $3, acc2
+	CMOVQCS t0, acc0
+	CMOVQCS t1, acc1
+	CMOVQCS t2, acc2
+
+	// Add in the "s" part of the key
+	ADDQ 0+sStore, acc0
+	ADCQ 8+sStore, acc1
+
+	// Finally, constant time compare to the tag at the end of the message
+	XORQ    AX, AX
+	MOVQ    $1, DX
+	XORQ    (0*8)(inp), acc0
+	XORQ    (1*8)(inp), acc1
+	ORQ     acc1, acc0
+	CMOVQEQ DX, AX
+
+	// Return true iff tags are equal
+	MOVB AX, ret+96(FP)
+	RET
+
+// ----------------------------------------------------------------------------
+// Special optimization for buffers smaller than 129 bytes
+openSSE128:
+	// For up to 128 bytes of ciphertext and 64 bytes for the poly key, we require to process three blocks
+	MOVOU ·chacha20Constants<>(SB), A0; MOVOU (1*16)(keyp), B0; MOVOU (2*16)(keyp), C0; MOVOU (3*16)(keyp), D0
+	MOVO  A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1
+	MOVO  A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2
+	MOVO  B0, T1; MOVO C0, T2; MOVO D1, T3
+	MOVQ  $10, itr2
+
+openSSE128InnerCipherLoop:
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Left;  shiftB1Left; shiftB2Left
+	shiftC0Left;  shiftC1Left; shiftC2Left
+	shiftD0Left;  shiftD1Left; shiftD2Left
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Right; shiftB1Right; shiftB2Right
+	shiftC0Right; shiftC1Right; shiftC2Right
+	shiftD0Right; shiftD1Right; shiftD2Right
+	DECQ          itr2
+	JNE           openSSE128InnerCipherLoop
+
+	// A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded
+	PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2
+	PADDL T1, B0; PADDL T1, B1; PADDL T1, B2
+	PADDL T2, C1; PADDL T2, C2
+	PADDL T3, D1; PADDL ·sseIncMask<>(SB), T3; PADDL T3, D2
+
+	// Clamp and store the key
+	PAND  ·polyClampMask<>(SB), A0
+	MOVOU A0, rStore; MOVOU B0, sStore
+
+	// Hash
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+
+openSSE128Open:
+	CMPQ inl, $16
+	JB   openSSETail16
+	SUBQ $16, inl
+
+	// Load for hashing
+	polyAdd(0(inp))
+
+	// Load for decryption
+	MOVOU (inp), T0; PXOR T0, A1; MOVOU A1, (oup)
+	LEAQ  (1*16)(inp), inp
+	LEAQ  (1*16)(oup), oup
+	polyMul
+
+	// Shift the stream "left"
+	MOVO B1, A1
+	MOVO C1, B1
+	MOVO D1, C1
+	MOVO A2, D1
+	MOVO B2, A2
+	MOVO C2, B2
+	MOVO D2, C2
+	JMP  openSSE128Open
+
+openSSETail16:
+	TESTQ inl, inl
+	JE    openSSEFinalize
+
+	// We can safely load the CT from the end, because it is padded with the MAC
+	MOVQ   inl, itr2
+	SHLQ   $4, itr2
+	LEAQ   ·andMask<>(SB), t0
+	MOVOU  (inp), T0
+	ADDQ   inl, inp
+	PAND   -16(t0)(itr2*1), T0
+	MOVO   T0, 0+tmpStore
+	MOVQ   T0, t0
+	MOVQ   8+tmpStore, t1
+	PXOR   A1, T0
+
+	// We can only store one byte at a time, since plaintext can be shorter than 16 bytes
+openSSETail16Store:
+	MOVQ T0, t3
+	MOVB t3, (oup)
+	PSRLDQ $1, T0
+	INCQ   oup
+	DECQ   inl
+	JNE    openSSETail16Store
+	ADDQ   t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2
+	polyMul
+	JMP    openSSEFinalize
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 64 bytes of ciphertext
+openSSETail64:
+	// Need to decrypt up to 64 bytes - prepare single block
+	MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr0Store
+	XORQ itr2, itr2
+	MOVQ inl, itr1
+	CMPQ itr1, $16
+	JB   openSSETail64LoopB
+
+openSSETail64LoopA:
+	// Perform ChaCha rounds, while hashing the remaining input
+	polyAdd(0(inp)(itr2*1))
+	polyMul
+	SUBQ $16, itr1
+
+openSSETail64LoopB:
+	ADDQ          $16, itr2
+	chachaQR(A0, B0, C0, D0, T0)
+	shiftB0Left;  shiftC0Left; shiftD0Left
+	chachaQR(A0, B0, C0, D0, T0)
+	shiftB0Right; shiftC0Right; shiftD0Right
+
+	CMPQ itr1, $16
+	JAE  openSSETail64LoopA
+
+	CMPQ itr2, $160
+	JNE  openSSETail64LoopB
+
+	PADDL ·chacha20Constants<>(SB), A0; PADDL state1Store, B0; PADDL state2Store, C0; PADDL ctr0Store, D0
+
+openSSETail64DecLoop:
+	CMPQ  inl, $16
+	JB    openSSETail64DecLoopDone
+	SUBQ  $16, inl
+	MOVOU (inp), T0
+	PXOR  T0, A0
+	MOVOU A0, (oup)
+	LEAQ  16(inp), inp
+	LEAQ  16(oup), oup
+	MOVO  B0, A0
+	MOVO  C0, B0
+	MOVO  D0, C0
+	JMP   openSSETail64DecLoop
+
+openSSETail64DecLoopDone:
+	MOVO A0, A1
+	JMP  openSSETail16
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 128 bytes of ciphertext
+openSSETail128:
+	// Need to decrypt up to 128 bytes - prepare two blocks
+	MOVO ·chacha20Constants<>(SB), A1; MOVO state1Store, B1; MOVO state2Store, C1; MOVO ctr3Store, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr0Store
+	MOVO A1, A0; MOVO B1, B0; MOVO C1, C0; MOVO D1, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr1Store
+	XORQ itr2, itr2
+	MOVQ inl, itr1
+	ANDQ $-16, itr1
+
+openSSETail128LoopA:
+	// Perform ChaCha rounds, while hashing the remaining input
+	polyAdd(0(inp)(itr2*1))
+	polyMul
+
+openSSETail128LoopB:
+	ADDQ          $16, itr2
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0)
+	shiftB0Left;  shiftC0Left; shiftD0Left
+	shiftB1Left;  shiftC1Left; shiftD1Left
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0)
+	shiftB0Right; shiftC0Right; shiftD0Right
+	shiftB1Right; shiftC1Right; shiftD1Right
+
+	CMPQ itr2, itr1
+	JB   openSSETail128LoopA
+
+	CMPQ itr2, $160
+	JNE  openSSETail128LoopB
+
+	PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1
+	PADDL state1Store, B0; PADDL state1Store, B1
+	PADDL state2Store, C0; PADDL state2Store, C1
+	PADDL ctr1Store, D0; PADDL ctr0Store, D1
+
+	MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3
+	PXOR  T0, A1; PXOR T1, B1; PXOR T2, C1; PXOR T3, D1
+	MOVOU A1, (0*16)(oup); MOVOU B1, (1*16)(oup); MOVOU C1, (2*16)(oup); MOVOU D1, (3*16)(oup)
+
+	SUBQ $64, inl
+	LEAQ 64(inp), inp
+	LEAQ 64(oup), oup
+	JMP  openSSETail64DecLoop
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 192 bytes of ciphertext
+openSSETail192:
+	// Need to decrypt up to 192 bytes - prepare three blocks
+	MOVO ·chacha20Constants<>(SB), A2; MOVO state1Store, B2; MOVO state2Store, C2; MOVO ctr3Store, D2; PADDL ·sseIncMask<>(SB), D2; MOVO D2, ctr0Store
+	MOVO A2, A1; MOVO B2, B1; MOVO C2, C1; MOVO D2, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr1Store
+	MOVO A1, A0; MOVO B1, B0; MOVO C1, C0; MOVO D1, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr2Store
+
+	MOVQ    inl, itr1
+	MOVQ    $160, itr2
+	CMPQ    itr1, $160
+	CMOVQGT itr2, itr1
+	ANDQ    $-16, itr1
+	XORQ    itr2, itr2
+
+openSSLTail192LoopA:
+	// Perform ChaCha rounds, while hashing the remaining input
+	polyAdd(0(inp)(itr2*1))
+	polyMul
+
+openSSLTail192LoopB:
+	ADDQ         $16, itr2
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Left; shiftC0Left; shiftD0Left
+	shiftB1Left; shiftC1Left; shiftD1Left
+	shiftB2Left; shiftC2Left; shiftD2Left
+
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Right; shiftC0Right; shiftD0Right
+	shiftB1Right; shiftC1Right; shiftD1Right
+	shiftB2Right; shiftC2Right; shiftD2Right
+
+	CMPQ itr2, itr1
+	JB   openSSLTail192LoopA
+
+	CMPQ itr2, $160
+	JNE  openSSLTail192LoopB
+
+	CMPQ inl, $176
+	JB   openSSLTail192Store
+
+	polyAdd(160(inp))
+	polyMul
+
+	CMPQ inl, $192
+	JB   openSSLTail192Store
+
+	polyAdd(176(inp))
+	polyMul
+
+openSSLTail192Store:
+	PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2
+	PADDL state1Store, B0; PADDL state1Store, B1; PADDL state1Store, B2
+	PADDL state2Store, C0; PADDL state2Store, C1; PADDL state2Store, C2
+	PADDL ctr2Store, D0; PADDL ctr1Store, D1; PADDL ctr0Store, D2
+
+	MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3
+	PXOR  T0, A2; PXOR T1, B2; PXOR T2, C2; PXOR T3, D2
+	MOVOU A2, (0*16)(oup); MOVOU B2, (1*16)(oup); MOVOU C2, (2*16)(oup); MOVOU D2, (3*16)(oup)
+
+	MOVOU (4*16)(inp), T0; MOVOU (5*16)(inp), T1; MOVOU (6*16)(inp), T2; MOVOU (7*16)(inp), T3
+	PXOR  T0, A1; PXOR T1, B1; PXOR T2, C1; PXOR T3, D1
+	MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup)
+
+	SUBQ $128, inl
+	LEAQ 128(inp), inp
+	LEAQ 128(oup), oup
+	JMP  openSSETail64DecLoop
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 256 bytes of ciphertext
+openSSETail256:
+	// Need to decrypt up to 256 bytes - prepare four blocks
+	MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0
+	MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1
+	MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2
+	MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3
+
+	// Store counters
+	MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store
+	XORQ itr2, itr2
+
+openSSETail256Loop:
+	// This loop inteleaves 8 ChaCha quarter rounds with 1 poly multiplication
+	polyAdd(0(inp)(itr2*1))
+	MOVO          C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO          tmpStore, C3
+	MOVO          C1, tmpStore
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO          tmpStore, C1
+	shiftB0Left;  shiftB1Left; shiftB2Left; shiftB3Left
+	shiftC0Left;  shiftC1Left; shiftC2Left; shiftC3Left
+	shiftD0Left;  shiftD1Left; shiftD2Left; shiftD3Left
+	polyMulStage1
+	polyMulStage2
+	MOVO          C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO          tmpStore, C3
+	MOVO          C1, tmpStore
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO          tmpStore, C1
+	polyMulStage3
+	polyMulReduceStage
+	shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right
+	shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right
+	shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right
+	ADDQ          $2*8, itr2
+	CMPQ          itr2, $160
+	JB            openSSETail256Loop
+	MOVQ          inl, itr1
+	ANDQ          $-16, itr1
+
+openSSETail256HashLoop:
+	polyAdd(0(inp)(itr2*1))
+	polyMul
+	ADDQ $2*8, itr2
+	CMPQ itr2, itr1
+	JB   openSSETail256HashLoop
+
+	// Add in the state
+	PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3
+	PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3
+	PADDD state2Store, C0; PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3
+	PADDD ctr0Store, D0; PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3
+	MOVO  D3, tmpStore
+
+	// Load - xor - store
+	MOVOU (0*16)(inp), D3; PXOR D3, A0
+	MOVOU (1*16)(inp), D3; PXOR D3, B0
+	MOVOU (2*16)(inp), D3; PXOR D3, C0
+	MOVOU (3*16)(inp), D3; PXOR D3, D0
+	MOVOU A0, (0*16)(oup)
+	MOVOU B0, (1*16)(oup)
+	MOVOU C0, (2*16)(oup)
+	MOVOU D0, (3*16)(oup)
+	MOVOU (4*16)(inp), A0; MOVOU (5*16)(inp), B0; MOVOU (6*16)(inp), C0; MOVOU (7*16)(inp), D0
+	PXOR  A0, A1; PXOR B0, B1; PXOR C0, C1; PXOR D0, D1
+	MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup)
+	MOVOU (8*16)(inp), A0; MOVOU (9*16)(inp), B0; MOVOU (10*16)(inp), C0; MOVOU (11*16)(inp), D0
+	PXOR  A0, A2; PXOR B0, B2; PXOR C0, C2; PXOR D0, D2
+	MOVOU A2, (8*16)(oup); MOVOU B2, (9*16)(oup); MOVOU C2, (10*16)(oup); MOVOU D2, (11*16)(oup)
+	LEAQ  192(inp), inp
+	LEAQ  192(oup), oup
+	SUBQ  $192, inl
+	MOVO  A3, A0
+	MOVO  B3, B0
+	MOVO  C3, C0
+	MOVO  tmpStore, D0
+
+	JMP openSSETail64DecLoop
+
+// ----------------------------------------------------------------------------
+// ------------------------- AVX2 Code ----------------------------------------
+chacha20Poly1305Open_AVX2:
+	VZEROUPPER
+	VMOVDQU ·chacha20Constants<>(SB), AA0
+	BYTE    $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x70; BYTE $0x10 // broadcasti128 16(r8), ymm14
+	BYTE    $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x20 // broadcasti128 32(r8), ymm12
+	BYTE    $0xc4; BYTE $0xc2; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x30 // broadcasti128 48(r8), ymm4
+	VPADDD  ·avx2InitMask<>(SB), DD0, DD0
+
+	// Special optimization, for very short buffers
+	CMPQ inl, $192
+	JBE  openAVX2192
+	CMPQ inl, $320
+	JBE  openAVX2320
+
+	// For the general key prepare the key first - as a byproduct we have 64 bytes of cipher stream
+	VMOVDQA BB0, state1StoreAVX2
+	VMOVDQA CC0, state2StoreAVX2
+	VMOVDQA DD0, ctr3StoreAVX2
+	MOVQ    $10, itr2
+
+openAVX2PreparePolyKey:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0)
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $12, DD0, DD0, DD0
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0)
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $4, DD0, DD0, DD0
+	DECQ     itr2
+	JNE      openAVX2PreparePolyKey
+
+	VPADDD ·chacha20Constants<>(SB), AA0, AA0
+	VPADDD state1StoreAVX2, BB0, BB0
+	VPADDD state2StoreAVX2, CC0, CC0
+	VPADDD ctr3StoreAVX2, DD0, DD0
+
+	VPERM2I128 $0x02, AA0, BB0, TT0
+
+	// Clamp and store poly key
+	VPAND   ·polyClampMask<>(SB), TT0, TT0
+	VMOVDQA TT0, rsStoreAVX2
+
+	// Stream for the first 64 bytes
+	VPERM2I128 $0x13, AA0, BB0, AA0
+	VPERM2I128 $0x13, CC0, DD0, BB0
+
+	// Hash AD + first 64 bytes
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+	XORQ itr1, itr1
+
+openAVX2InitialHash64:
+	polyAdd(0(inp)(itr1*1))
+	polyMulAVX2
+	ADDQ $16, itr1
+	CMPQ itr1, $64
+	JNE  openAVX2InitialHash64
+
+	// Decrypt the first 64 bytes
+	VPXOR   (0*32)(inp), AA0, AA0
+	VPXOR   (1*32)(inp), BB0, BB0
+	VMOVDQU AA0, (0*32)(oup)
+	VMOVDQU BB0, (1*32)(oup)
+	LEAQ    (2*32)(inp), inp
+	LEAQ    (2*32)(oup), oup
+	SUBQ    $64, inl
+
+openAVX2MainLoop:
+	CMPQ inl, $512
+	JB   openAVX2MainLoopDone
+
+	// Load state, increment counter blocks, store the incremented counters
+	VMOVDQU ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3
+	VMOVDQA ctr3StoreAVX2, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3
+	VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2
+	XORQ    itr1, itr1
+
+openAVX2InternalLoop:
+	// Lets just say this spaghetti loop interleaves 2 quarter rounds with 3 poly multiplications
+	// Effectively per 512 bytes of stream we hash 480 bytes of ciphertext
+	polyAdd(0*8(inp)(itr1*1))
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	polyMulStage1_AVX2
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	polyMulStage2_AVX2
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	polyMulStage3_AVX2
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyMulReduceStage
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	polyAdd(2*8(inp)(itr1*1))
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	polyMulStage1_AVX2
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyMulStage2_AVX2
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	polyMulStage3_AVX2
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	polyMulReduceStage
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	polyAdd(4*8(inp)(itr1*1))
+	LEAQ     (6*8)(itr1), itr1
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyMulStage1_AVX2
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	polyMulStage2_AVX2
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	polyMulStage3_AVX2
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyMulReduceStage
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3
+	CMPQ     itr1, $480
+	JNE      openAVX2InternalLoop
+
+	VPADDD  ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3
+	VPADDD  state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3
+	VPADDD  state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3
+	VPADDD  ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3
+	VMOVDQA CC3, tmpStoreAVX2
+
+	// We only hashed 480 of the 512 bytes available - hash the remaining 32 here
+	polyAdd(480(inp))
+	polyMulAVX2
+	VPERM2I128 $0x02, AA0, BB0, CC3; VPERM2I128 $0x13, AA0, BB0, BB0; VPERM2I128 $0x02, CC0, DD0, AA0; VPERM2I128 $0x13, CC0, DD0, CC0
+	VPXOR      (0*32)(inp), CC3, CC3; VPXOR (1*32)(inp), AA0, AA0; VPXOR (2*32)(inp), BB0, BB0; VPXOR (3*32)(inp), CC0, CC0
+	VMOVDQU    CC3, (0*32)(oup); VMOVDQU AA0, (1*32)(oup); VMOVDQU BB0, (2*32)(oup); VMOVDQU CC0, (3*32)(oup)
+	VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0
+	VPXOR      (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup)
+
+	// and here
+	polyAdd(496(inp))
+	polyMulAVX2
+	VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0
+	VPXOR      (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup)
+	VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0
+	VPXOR      (12*32)(inp), AA0, AA0; VPXOR (13*32)(inp), BB0, BB0; VPXOR (14*32)(inp), CC0, CC0; VPXOR (15*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (12*32)(oup); VMOVDQU BB0, (13*32)(oup); VMOVDQU CC0, (14*32)(oup); VMOVDQU DD0, (15*32)(oup)
+	LEAQ       (32*16)(inp), inp
+	LEAQ       (32*16)(oup), oup
+	SUBQ       $(32*16), inl
+	JMP        openAVX2MainLoop
+
+openAVX2MainLoopDone:
+	// Handle the various tail sizes efficiently
+	TESTQ inl, inl
+	JE    openSSEFinalize
+	CMPQ  inl, $128
+	JBE   openAVX2Tail128
+	CMPQ  inl, $256
+	JBE   openAVX2Tail256
+	CMPQ  inl, $384
+	JBE   openAVX2Tail384
+	JMP   openAVX2Tail512
+
+// ----------------------------------------------------------------------------
+// Special optimization for buffers smaller than 193 bytes
+openAVX2192:
+	// For up to 192 bytes of ciphertext and 64 bytes for the poly key, we process four blocks
+	VMOVDQA AA0, AA1
+	VMOVDQA BB0, BB1
+	VMOVDQA CC0, CC1
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD1
+	VMOVDQA AA0, AA2
+	VMOVDQA BB0, BB2
+	VMOVDQA CC0, CC2
+	VMOVDQA DD0, DD2
+	VMOVDQA DD1, TT3
+	MOVQ    $10, itr2
+
+openAVX2192InnerCipherLoop:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR   $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1
+	VPALIGNR   $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR   $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR   $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1
+	VPALIGNR   $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR   $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1
+	DECQ       itr2
+	JNE        openAVX2192InnerCipherLoop
+	VPADDD     AA2, AA0, AA0; VPADDD AA2, AA1, AA1
+	VPADDD     BB2, BB0, BB0; VPADDD BB2, BB1, BB1
+	VPADDD     CC2, CC0, CC0; VPADDD CC2, CC1, CC1
+	VPADDD     DD2, DD0, DD0; VPADDD TT3, DD1, DD1
+	VPERM2I128 $0x02, AA0, BB0, TT0
+
+	// Clamp and store poly key
+	VPAND   ·polyClampMask<>(SB), TT0, TT0
+	VMOVDQA TT0, rsStoreAVX2
+
+	// Stream for up to 192 bytes
+	VPERM2I128 $0x13, AA0, BB0, AA0
+	VPERM2I128 $0x13, CC0, DD0, BB0
+	VPERM2I128 $0x02, AA1, BB1, CC0
+	VPERM2I128 $0x02, CC1, DD1, DD0
+	VPERM2I128 $0x13, AA1, BB1, AA1
+	VPERM2I128 $0x13, CC1, DD1, BB1
+
+openAVX2ShortOpen:
+	// Hash
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+
+openAVX2ShortOpenLoop:
+	CMPQ inl, $32
+	JB   openAVX2ShortTail32
+	SUBQ $32, inl
+
+	// Load for hashing
+	polyAdd(0*8(inp))
+	polyMulAVX2
+	polyAdd(2*8(inp))
+	polyMulAVX2
+
+	// Load for decryption
+	VPXOR   (inp), AA0, AA0
+	VMOVDQU AA0, (oup)
+	LEAQ    (1*32)(inp), inp
+	LEAQ    (1*32)(oup), oup
+
+	// Shift stream left
+	VMOVDQA BB0, AA0
+	VMOVDQA CC0, BB0
+	VMOVDQA DD0, CC0
+	VMOVDQA AA1, DD0
+	VMOVDQA BB1, AA1
+	VMOVDQA CC1, BB1
+	VMOVDQA DD1, CC1
+	VMOVDQA AA2, DD1
+	VMOVDQA BB2, AA2
+	JMP     openAVX2ShortOpenLoop
+
+openAVX2ShortTail32:
+	CMPQ    inl, $16
+	VMOVDQA A0, A1
+	JB      openAVX2ShortDone
+
+	SUBQ $16, inl
+
+	// Load for hashing
+	polyAdd(0*8(inp))
+	polyMulAVX2
+
+	// Load for decryption
+	VPXOR      (inp), A0, T0
+	VMOVDQU    T0, (oup)
+	LEAQ       (1*16)(inp), inp
+	LEAQ       (1*16)(oup), oup
+	VPERM2I128 $0x11, AA0, AA0, AA0
+	VMOVDQA    A0, A1
+
+openAVX2ShortDone:
+	VZEROUPPER
+	JMP openSSETail16
+
+// ----------------------------------------------------------------------------
+// Special optimization for buffers smaller than 321 bytes
+openAVX2320:
+	// For up to 320 bytes of ciphertext and 64 bytes for the poly key, we process six blocks
+	VMOVDQA AA0, AA1; VMOVDQA BB0, BB1; VMOVDQA CC0, CC1; VPADDD ·avx2IncMask<>(SB), DD0, DD1
+	VMOVDQA AA0, AA2; VMOVDQA BB0, BB2; VMOVDQA CC0, CC2; VPADDD ·avx2IncMask<>(SB), DD1, DD2
+	VMOVDQA BB0, TT1; VMOVDQA CC0, TT2; VMOVDQA DD0, TT3
+	MOVQ    $10, itr2
+
+openAVX2320InnerCipherLoop:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2
+	DECQ     itr2
+	JNE      openAVX2320InnerCipherLoop
+
+	VMOVDQA ·chacha20Constants<>(SB), TT0
+	VPADDD  TT0, AA0, AA0; VPADDD TT0, AA1, AA1; VPADDD TT0, AA2, AA2
+	VPADDD  TT1, BB0, BB0; VPADDD TT1, BB1, BB1; VPADDD TT1, BB2, BB2
+	VPADDD  TT2, CC0, CC0; VPADDD TT2, CC1, CC1; VPADDD TT2, CC2, CC2
+	VMOVDQA ·avx2IncMask<>(SB), TT0
+	VPADDD  TT3, DD0, DD0; VPADDD TT0, TT3, TT3
+	VPADDD  TT3, DD1, DD1; VPADDD TT0, TT3, TT3
+	VPADDD  TT3, DD2, DD2
+
+	// Clamp and store poly key
+	VPERM2I128 $0x02, AA0, BB0, TT0
+	VPAND      ·polyClampMask<>(SB), TT0, TT0
+	VMOVDQA    TT0, rsStoreAVX2
+
+	// Stream for up to 320 bytes
+	VPERM2I128 $0x13, AA0, BB0, AA0
+	VPERM2I128 $0x13, CC0, DD0, BB0
+	VPERM2I128 $0x02, AA1, BB1, CC0
+	VPERM2I128 $0x02, CC1, DD1, DD0
+	VPERM2I128 $0x13, AA1, BB1, AA1
+	VPERM2I128 $0x13, CC1, DD1, BB1
+	VPERM2I128 $0x02, AA2, BB2, CC1
+	VPERM2I128 $0x02, CC2, DD2, DD1
+	VPERM2I128 $0x13, AA2, BB2, AA2
+	VPERM2I128 $0x13, CC2, DD2, BB2
+	JMP        openAVX2ShortOpen
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 128 bytes of ciphertext
+openAVX2Tail128:
+	// Need to decrypt up to 128 bytes - prepare two blocks
+	VMOVDQA ·chacha20Constants<>(SB), AA1
+	VMOVDQA state1StoreAVX2, BB1
+	VMOVDQA state2StoreAVX2, CC1
+	VMOVDQA ctr3StoreAVX2, DD1
+	VPADDD  ·avx2IncMask<>(SB), DD1, DD1
+	VMOVDQA DD1, DD0
+
+	XORQ  itr2, itr2
+	MOVQ  inl, itr1
+	ANDQ  $-16, itr1
+	TESTQ itr1, itr1
+	JE    openAVX2Tail128LoopB
+
+openAVX2Tail128LoopA:
+	// Perform ChaCha rounds, while hashing the remaining input
+	polyAdd(0(inp)(itr2*1))
+	polyMulAVX2
+
+openAVX2Tail128LoopB:
+	ADDQ     $16, itr2
+	chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR $4, BB1, BB1, BB1
+	VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR $12, DD1, DD1, DD1
+	chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR $12, BB1, BB1, BB1
+	VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR $4, DD1, DD1, DD1
+	CMPQ     itr2, itr1
+	JB       openAVX2Tail128LoopA
+	CMPQ     itr2, $160
+	JNE      openAVX2Tail128LoopB
+
+	VPADDD     ·chacha20Constants<>(SB), AA1, AA1
+	VPADDD     state1StoreAVX2, BB1, BB1
+	VPADDD     state2StoreAVX2, CC1, CC1
+	VPADDD     DD0, DD1, DD1
+	VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0
+
+openAVX2TailLoop:
+	CMPQ inl, $32
+	JB   openAVX2Tail
+	SUBQ $32, inl
+
+	// Load for decryption
+	VPXOR   (inp), AA0, AA0
+	VMOVDQU AA0, (oup)
+	LEAQ    (1*32)(inp), inp
+	LEAQ    (1*32)(oup), oup
+	VMOVDQA BB0, AA0
+	VMOVDQA CC0, BB0
+	VMOVDQA DD0, CC0
+	JMP     openAVX2TailLoop
+
+openAVX2Tail:
+	CMPQ    inl, $16
+	VMOVDQA A0, A1
+	JB      openAVX2TailDone
+	SUBQ    $16, inl
+
+	// Load for decryption
+	VPXOR      (inp), A0, T0
+	VMOVDQU    T0, (oup)
+	LEAQ       (1*16)(inp), inp
+	LEAQ       (1*16)(oup), oup
+	VPERM2I128 $0x11, AA0, AA0, AA0
+	VMOVDQA    A0, A1
+
+openAVX2TailDone:
+	VZEROUPPER
+	JMP openSSETail16
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 256 bytes of ciphertext
+openAVX2Tail256:
+	// Need to decrypt up to 256 bytes - prepare four blocks
+	VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1
+	VMOVDQA ctr3StoreAVX2, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD1
+	VMOVDQA DD0, TT1
+	VMOVDQA DD1, TT2
+
+	// Compute the number of iterations that will hash data
+	MOVQ    inl, tmpStoreAVX2
+	MOVQ    inl, itr1
+	SUBQ    $128, itr1
+	SHRQ    $4, itr1
+	MOVQ    $10, itr2
+	CMPQ    itr1, $10
+	CMOVQGT itr2, itr1
+	MOVQ    inp, inl
+	XORQ    itr2, itr2
+
+openAVX2Tail256LoopA:
+	polyAdd(0(inl))
+	polyMulAVX2
+	LEAQ 16(inl), inl
+
+	// Perform ChaCha rounds, while hashing the remaining input
+openAVX2Tail256LoopB:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1
+	INCQ     itr2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1
+	CMPQ     itr2, itr1
+	JB       openAVX2Tail256LoopA
+
+	CMPQ itr2, $10
+	JNE  openAVX2Tail256LoopB
+
+	MOVQ inl, itr2
+	SUBQ inp, inl
+	MOVQ inl, itr1
+	MOVQ tmpStoreAVX2, inl
+
+	// Hash the remainder of data (if any)
+openAVX2Tail256Hash:
+	ADDQ $16, itr1
+	CMPQ itr1, inl
+	JGT  openAVX2Tail256HashEnd
+	polyAdd (0(itr2))
+	polyMulAVX2
+	LEAQ 16(itr2), itr2
+	JMP  openAVX2Tail256Hash
+
+// Store 128 bytes safely, then go to store loop
+openAVX2Tail256HashEnd:
+	VPADDD     ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1
+	VPADDD     state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1
+	VPADDD     state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1
+	VPADDD     TT1, DD0, DD0; VPADDD TT2, DD1, DD1
+	VPERM2I128 $0x02, AA0, BB0, AA2; VPERM2I128 $0x02, CC0, DD0, BB2; VPERM2I128 $0x13, AA0, BB0, CC2; VPERM2I128 $0x13, CC0, DD0, DD2
+	VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0
+
+	VPXOR   (0*32)(inp), AA2, AA2; VPXOR (1*32)(inp), BB2, BB2; VPXOR (2*32)(inp), CC2, CC2; VPXOR (3*32)(inp), DD2, DD2
+	VMOVDQU AA2, (0*32)(oup); VMOVDQU BB2, (1*32)(oup); VMOVDQU CC2, (2*32)(oup); VMOVDQU DD2, (3*32)(oup)
+	LEAQ    (4*32)(inp), inp
+	LEAQ    (4*32)(oup), oup
+	SUBQ    $4*32, inl
+
+	JMP openAVX2TailLoop
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 384 bytes of ciphertext
+openAVX2Tail384:
+	// Need to decrypt up to 384 bytes - prepare six blocks
+	VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2
+	VMOVDQA ctr3StoreAVX2, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD1
+	VPADDD  ·avx2IncMask<>(SB), DD1, DD2
+	VMOVDQA DD0, ctr0StoreAVX2
+	VMOVDQA DD1, ctr1StoreAVX2
+	VMOVDQA DD2, ctr2StoreAVX2
+
+	// Compute the number of iterations that will hash two blocks of data
+	MOVQ    inl, tmpStoreAVX2
+	MOVQ    inl, itr1
+	SUBQ    $256, itr1
+	SHRQ    $4, itr1
+	ADDQ    $6, itr1
+	MOVQ    $10, itr2
+	CMPQ    itr1, $10
+	CMOVQGT itr2, itr1
+	MOVQ    inp, inl
+	XORQ    itr2, itr2
+
+	// Perform ChaCha rounds, while hashing the remaining input
+openAVX2Tail384LoopB:
+	polyAdd(0(inl))
+	polyMulAVX2
+	LEAQ 16(inl), inl
+
+openAVX2Tail384LoopA:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2
+	polyAdd(0(inl))
+	polyMulAVX2
+	LEAQ     16(inl), inl
+	INCQ     itr2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2
+
+	CMPQ itr2, itr1
+	JB   openAVX2Tail384LoopB
+
+	CMPQ itr2, $10
+	JNE  openAVX2Tail384LoopA
+
+	MOVQ inl, itr2
+	SUBQ inp, inl
+	MOVQ inl, itr1
+	MOVQ tmpStoreAVX2, inl
+
+openAVX2Tail384Hash:
+	ADDQ $16, itr1
+	CMPQ itr1, inl
+	JGT  openAVX2Tail384HashEnd
+	polyAdd(0(itr2))
+	polyMulAVX2
+	LEAQ 16(itr2), itr2
+	JMP  openAVX2Tail384Hash
+
+// Store 256 bytes safely, then go to store loop
+openAVX2Tail384HashEnd:
+	VPADDD     ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2
+	VPADDD     state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2
+	VPADDD     state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2
+	VPADDD     ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2
+	VPERM2I128 $0x02, AA0, BB0, TT0; VPERM2I128 $0x02, CC0, DD0, TT1; VPERM2I128 $0x13, AA0, BB0, TT2; VPERM2I128 $0x13, CC0, DD0, TT3
+	VPXOR      (0*32)(inp), TT0, TT0; VPXOR (1*32)(inp), TT1, TT1; VPXOR (2*32)(inp), TT2, TT2; VPXOR (3*32)(inp), TT3, TT3
+	VMOVDQU    TT0, (0*32)(oup); VMOVDQU TT1, (1*32)(oup); VMOVDQU TT2, (2*32)(oup); VMOVDQU TT3, (3*32)(oup)
+	VPERM2I128 $0x02, AA1, BB1, TT0; VPERM2I128 $0x02, CC1, DD1, TT1; VPERM2I128 $0x13, AA1, BB1, TT2; VPERM2I128 $0x13, CC1, DD1, TT3
+	VPXOR      (4*32)(inp), TT0, TT0; VPXOR (5*32)(inp), TT1, TT1; VPXOR (6*32)(inp), TT2, TT2; VPXOR (7*32)(inp), TT3, TT3
+	VMOVDQU    TT0, (4*32)(oup); VMOVDQU TT1, (5*32)(oup); VMOVDQU TT2, (6*32)(oup); VMOVDQU TT3, (7*32)(oup)
+	VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0
+	LEAQ       (8*32)(inp), inp
+	LEAQ       (8*32)(oup), oup
+	SUBQ       $8*32, inl
+	JMP        openAVX2TailLoop
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 512 bytes of ciphertext
+openAVX2Tail512:
+	VMOVDQU ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3
+	VMOVDQA ctr3StoreAVX2, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3
+	VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2
+	XORQ    itr1, itr1
+	MOVQ    inp, itr2
+
+openAVX2Tail512LoopB:
+	polyAdd(0(itr2))
+	polyMulAVX2
+	LEAQ (2*8)(itr2), itr2
+
+openAVX2Tail512LoopA:
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyAdd(0*8(itr2))
+	polyMulAVX2
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	polyAdd(2*8(itr2))
+	polyMulAVX2
+	LEAQ     (4*8)(itr2), itr2
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3
+	INCQ     itr1
+	CMPQ     itr1, $4
+	JLT      openAVX2Tail512LoopB
+
+	CMPQ itr1, $10
+	JNE  openAVX2Tail512LoopA
+
+	MOVQ inl, itr1
+	SUBQ $384, itr1
+	ANDQ $-16, itr1
+
+openAVX2Tail512HashLoop:
+	TESTQ itr1, itr1
+	JE    openAVX2Tail512HashEnd
+	polyAdd(0(itr2))
+	polyMulAVX2
+	LEAQ  16(itr2), itr2
+	SUBQ  $16, itr1
+	JMP   openAVX2Tail512HashLoop
+
+openAVX2Tail512HashEnd:
+	VPADDD     ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3
+	VPADDD     state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3
+	VPADDD     state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3
+	VPADDD     ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3
+	VMOVDQA    CC3, tmpStoreAVX2
+	VPERM2I128 $0x02, AA0, BB0, CC3; VPERM2I128 $0x13, AA0, BB0, BB0; VPERM2I128 $0x02, CC0, DD0, AA0; VPERM2I128 $0x13, CC0, DD0, CC0
+	VPXOR      (0*32)(inp), CC3, CC3; VPXOR (1*32)(inp), AA0, AA0; VPXOR (2*32)(inp), BB0, BB0; VPXOR (3*32)(inp), CC0, CC0
+	VMOVDQU    CC3, (0*32)(oup); VMOVDQU AA0, (1*32)(oup); VMOVDQU BB0, (2*32)(oup); VMOVDQU CC0, (3*32)(oup)
+	VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0
+	VPXOR      (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup)
+	VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0
+	VPXOR      (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup)
+	VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0
+
+	LEAQ (12*32)(inp), inp
+	LEAQ (12*32)(oup), oup
+	SUBQ $12*32, inl
+
+	JMP openAVX2TailLoop
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+// func chacha20Poly1305Seal(dst, key, src, ad []byte)
+TEXT ·chacha20Poly1305Seal(SB), 0, $288-96
+	// For aligned stack access
+	MOVQ SP, BP
+	ADDQ $32, BP
+	ANDQ $-32, BP
+	MOVQ dst+0(FP), oup
+	MOVQ key+24(FP), keyp
+	MOVQ src+48(FP), inp
+	MOVQ src_len+56(FP), inl
+	MOVQ ad+72(FP), adp
+
+	CMPB ·useAVX2(SB), $1
+	JE   chacha20Poly1305Seal_AVX2
+
+	// Special optimization, for very short buffers
+	CMPQ inl, $128
+	JBE  sealSSE128 // About 15% faster
+
+	// In the seal case - prepare the poly key + 3 blocks of stream in the first iteration
+	MOVOU ·chacha20Constants<>(SB), A0
+	MOVOU (1*16)(keyp), B0
+	MOVOU (2*16)(keyp), C0
+	MOVOU (3*16)(keyp), D0
+
+	// Store state on stack for future use
+	MOVO B0, state1Store
+	MOVO C0, state2Store
+
+	// Load state, increment counter blocks
+	MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1
+	MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2
+	MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3
+
+	// Store counters
+	MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store
+	MOVQ $10, itr2
+
+sealSSEIntroLoop:
+	MOVO         C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO         tmpStore, C3
+	MOVO         C1, tmpStore
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO         tmpStore, C1
+	shiftB0Left; shiftB1Left; shiftB2Left; shiftB3Left
+	shiftC0Left; shiftC1Left; shiftC2Left; shiftC3Left
+	shiftD0Left; shiftD1Left; shiftD2Left; shiftD3Left
+
+	MOVO          C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO          tmpStore, C3
+	MOVO          C1, tmpStore
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO          tmpStore, C1
+	shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right
+	shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right
+	shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right
+	DECQ          itr2
+	JNE           sealSSEIntroLoop
+
+	// Add in the state
+	PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3
+	PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3
+	PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3
+	PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3
+
+	// Clamp and store the key
+	PAND ·polyClampMask<>(SB), A0
+	MOVO A0, rStore
+	MOVO B0, sStore
+
+	// Hash AAD
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+
+	MOVOU (0*16)(inp), A0; MOVOU (1*16)(inp), B0; MOVOU (2*16)(inp), C0; MOVOU (3*16)(inp), D0
+	PXOR  A0, A1; PXOR B0, B1; PXOR C0, C1; PXOR D0, D1
+	MOVOU A1, (0*16)(oup); MOVOU B1, (1*16)(oup); MOVOU C1, (2*16)(oup); MOVOU D1, (3*16)(oup)
+	MOVOU (4*16)(inp), A0; MOVOU (5*16)(inp), B0; MOVOU (6*16)(inp), C0; MOVOU (7*16)(inp), D0
+	PXOR  A0, A2; PXOR B0, B2; PXOR C0, C2; PXOR D0, D2
+	MOVOU A2, (4*16)(oup); MOVOU B2, (5*16)(oup); MOVOU C2, (6*16)(oup); MOVOU D2, (7*16)(oup)
+
+	MOVQ $128, itr1
+	SUBQ $128, inl
+	LEAQ 128(inp), inp
+
+	MOVO A3, A1; MOVO B3, B1; MOVO C3, C1; MOVO D3, D1
+
+	CMPQ inl, $64
+	JBE  sealSSE128SealHash
+
+	MOVOU (0*16)(inp), A0; MOVOU (1*16)(inp), B0; MOVOU (2*16)(inp), C0; MOVOU (3*16)(inp), D0
+	PXOR  A0, A3; PXOR B0, B3; PXOR C0, C3; PXOR D0, D3
+	MOVOU A3, (8*16)(oup); MOVOU B3, (9*16)(oup); MOVOU C3, (10*16)(oup); MOVOU D3, (11*16)(oup)
+
+	ADDQ $64, itr1
+	SUBQ $64, inl
+	LEAQ 64(inp), inp
+
+	MOVQ $2, itr1
+	MOVQ $8, itr2
+
+	CMPQ inl, $64
+	JBE  sealSSETail64
+	CMPQ inl, $128
+	JBE  sealSSETail128
+	CMPQ inl, $192
+	JBE  sealSSETail192
+
+sealSSEMainLoop:
+	// Load state, increment counter blocks
+	MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0
+	MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1
+	MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2
+	MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3
+
+	// Store counters
+	MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store
+
+sealSSEInnerLoop:
+	MOVO          C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO          tmpStore, C3
+	MOVO          C1, tmpStore
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO          tmpStore, C1
+	polyAdd(0(oup))
+	shiftB0Left;  shiftB1Left; shiftB2Left; shiftB3Left
+	shiftC0Left;  shiftC1Left; shiftC2Left; shiftC3Left
+	shiftD0Left;  shiftD1Left; shiftD2Left; shiftD3Left
+	polyMulStage1
+	polyMulStage2
+	LEAQ          (2*8)(oup), oup
+	MOVO          C3, tmpStore
+	chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3)
+	MOVO          tmpStore, C3
+	MOVO          C1, tmpStore
+	polyMulStage3
+	chachaQR(A3, B3, C3, D3, C1)
+	MOVO          tmpStore, C1
+	polyMulReduceStage
+	shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right
+	shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right
+	shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right
+	DECQ          itr2
+	JGE           sealSSEInnerLoop
+	polyAdd(0(oup))
+	polyMul
+	LEAQ          (2*8)(oup), oup
+	DECQ          itr1
+	JG            sealSSEInnerLoop
+
+	// Add in the state
+	PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3
+	PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3
+	PADDD state2Store, C0; PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3
+	PADDD ctr0Store, D0; PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3
+	MOVO  D3, tmpStore
+
+	// Load - xor - store
+	MOVOU (0*16)(inp), D3; PXOR D3, A0
+	MOVOU (1*16)(inp), D3; PXOR D3, B0
+	MOVOU (2*16)(inp), D3; PXOR D3, C0
+	MOVOU (3*16)(inp), D3; PXOR D3, D0
+	MOVOU A0, (0*16)(oup)
+	MOVOU B0, (1*16)(oup)
+	MOVOU C0, (2*16)(oup)
+	MOVOU D0, (3*16)(oup)
+	MOVO  tmpStore, D3
+
+	MOVOU (4*16)(inp), A0; MOVOU (5*16)(inp), B0; MOVOU (6*16)(inp), C0; MOVOU (7*16)(inp), D0
+	PXOR  A0, A1; PXOR B0, B1; PXOR C0, C1; PXOR D0, D1
+	MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup)
+	MOVOU (8*16)(inp), A0; MOVOU (9*16)(inp), B0; MOVOU (10*16)(inp), C0; MOVOU (11*16)(inp), D0
+	PXOR  A0, A2; PXOR B0, B2; PXOR C0, C2; PXOR D0, D2
+	MOVOU A2, (8*16)(oup); MOVOU B2, (9*16)(oup); MOVOU C2, (10*16)(oup); MOVOU D2, (11*16)(oup)
+	ADDQ  $192, inp
+	MOVQ  $192, itr1
+	SUBQ  $192, inl
+	MOVO  A3, A1
+	MOVO  B3, B1
+	MOVO  C3, C1
+	MOVO  D3, D1
+	CMPQ  inl, $64
+	JBE   sealSSE128SealHash
+	MOVOU (0*16)(inp), A0; MOVOU (1*16)(inp), B0; MOVOU (2*16)(inp), C0; MOVOU (3*16)(inp), D0
+	PXOR  A0, A3; PXOR B0, B3; PXOR C0, C3; PXOR D0, D3
+	MOVOU A3, (12*16)(oup); MOVOU B3, (13*16)(oup); MOVOU C3, (14*16)(oup); MOVOU D3, (15*16)(oup)
+	LEAQ  64(inp), inp
+	SUBQ  $64, inl
+	MOVQ  $6, itr1
+	MOVQ  $4, itr2
+	CMPQ  inl, $192
+	JG    sealSSEMainLoop
+
+	MOVQ  inl, itr1
+	TESTQ inl, inl
+	JE    sealSSE128SealHash
+	MOVQ  $6, itr1
+	CMPQ  inl, $64
+	JBE   sealSSETail64
+	CMPQ  inl, $128
+	JBE   sealSSETail128
+	JMP   sealSSETail192
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 64 bytes of plaintext
+sealSSETail64:
+	// Need to encrypt up to 64 bytes - prepare single block, hash 192 or 256 bytes
+	MOVO  ·chacha20Constants<>(SB), A1
+	MOVO  state1Store, B1
+	MOVO  state2Store, C1
+	MOVO  ctr3Store, D1
+	PADDL ·sseIncMask<>(SB), D1
+	MOVO  D1, ctr0Store
+
+sealSSETail64LoopA:
+	// Perform ChaCha rounds, while hashing the previously encrypted ciphertext
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+sealSSETail64LoopB:
+	chachaQR(A1, B1, C1, D1, T1)
+	shiftB1Left;  shiftC1Left; shiftD1Left
+	chachaQR(A1, B1, C1, D1, T1)
+	shiftB1Right; shiftC1Right; shiftD1Right
+	polyAdd(0(oup))
+	polyMul
+	LEAQ          16(oup), oup
+
+	DECQ itr1
+	JG   sealSSETail64LoopA
+
+	DECQ  itr2
+	JGE   sealSSETail64LoopB
+	PADDL ·chacha20Constants<>(SB), A1
+	PADDL state1Store, B1
+	PADDL state2Store, C1
+	PADDL ctr0Store, D1
+
+	JMP sealSSE128Seal
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 128 bytes of plaintext
+sealSSETail128:
+	// Need to encrypt up to 128 bytes - prepare two blocks, hash 192 or 256 bytes
+	MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr0Store
+	MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr1Store
+
+sealSSETail128LoopA:
+	// Perform ChaCha rounds, while hashing the previously encrypted ciphertext
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+sealSSETail128LoopB:
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0)
+	shiftB0Left;  shiftC0Left; shiftD0Left
+	shiftB1Left;  shiftC1Left; shiftD1Left
+	polyAdd(0(oup))
+	polyMul
+	LEAQ          16(oup), oup
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0)
+	shiftB0Right; shiftC0Right; shiftD0Right
+	shiftB1Right; shiftC1Right; shiftD1Right
+
+	DECQ itr1
+	JG   sealSSETail128LoopA
+
+	DECQ itr2
+	JGE  sealSSETail128LoopB
+
+	PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1
+	PADDL state1Store, B0; PADDL state1Store, B1
+	PADDL state2Store, C0; PADDL state2Store, C1
+	PADDL ctr0Store, D0; PADDL ctr1Store, D1
+
+	MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3
+	PXOR  T0, A0; PXOR T1, B0; PXOR T2, C0; PXOR T3, D0
+	MOVOU A0, (0*16)(oup); MOVOU B0, (1*16)(oup); MOVOU C0, (2*16)(oup); MOVOU D0, (3*16)(oup)
+
+	MOVQ $64, itr1
+	LEAQ 64(inp), inp
+	SUBQ $64, inl
+
+	JMP sealSSE128SealHash
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 192 bytes of plaintext
+sealSSETail192:
+	// Need to encrypt up to 192 bytes - prepare three blocks, hash 192 or 256 bytes
+	MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr0Store
+	MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr1Store
+	MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2; MOVO D2, ctr2Store
+
+sealSSETail192LoopA:
+	// Perform ChaCha rounds, while hashing the previously encrypted ciphertext
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+sealSSETail192LoopB:
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Left; shiftC0Left; shiftD0Left
+	shiftB1Left; shiftC1Left; shiftD1Left
+	shiftB2Left; shiftC2Left; shiftD2Left
+
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Right; shiftC0Right; shiftD0Right
+	shiftB1Right; shiftC1Right; shiftD1Right
+	shiftB2Right; shiftC2Right; shiftD2Right
+
+	DECQ itr1
+	JG   sealSSETail192LoopA
+
+	DECQ itr2
+	JGE  sealSSETail192LoopB
+
+	PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2
+	PADDL state1Store, B0; PADDL state1Store, B1; PADDL state1Store, B2
+	PADDL state2Store, C0; PADDL state2Store, C1; PADDL state2Store, C2
+	PADDL ctr0Store, D0; PADDL ctr1Store, D1; PADDL ctr2Store, D2
+
+	MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3
+	PXOR  T0, A0; PXOR T1, B0; PXOR T2, C0; PXOR T3, D0
+	MOVOU A0, (0*16)(oup); MOVOU B0, (1*16)(oup); MOVOU C0, (2*16)(oup); MOVOU D0, (3*16)(oup)
+	MOVOU (4*16)(inp), T0; MOVOU (5*16)(inp), T1; MOVOU (6*16)(inp), T2; MOVOU (7*16)(inp), T3
+	PXOR  T0, A1; PXOR T1, B1; PXOR T2, C1; PXOR T3, D1
+	MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup)
+
+	MOVO A2, A1
+	MOVO B2, B1
+	MOVO C2, C1
+	MOVO D2, D1
+	MOVQ $128, itr1
+	LEAQ 128(inp), inp
+	SUBQ $128, inl
+
+	JMP sealSSE128SealHash
+
+// ----------------------------------------------------------------------------
+// Special seal optimization for buffers smaller than 129 bytes
+sealSSE128:
+	// For up to 128 bytes of ciphertext and 64 bytes for the poly key, we require to process three blocks
+	MOVOU ·chacha20Constants<>(SB), A0; MOVOU (1*16)(keyp), B0; MOVOU (2*16)(keyp), C0; MOVOU (3*16)(keyp), D0
+	MOVO  A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1
+	MOVO  A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2
+	MOVO  B0, T1; MOVO C0, T2; MOVO D1, T3
+	MOVQ  $10, itr2
+
+sealSSE128InnerCipherLoop:
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Left;  shiftB1Left; shiftB2Left
+	shiftC0Left;  shiftC1Left; shiftC2Left
+	shiftD0Left;  shiftD1Left; shiftD2Left
+	chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0)
+	shiftB0Right; shiftB1Right; shiftB2Right
+	shiftC0Right; shiftC1Right; shiftC2Right
+	shiftD0Right; shiftD1Right; shiftD2Right
+	DECQ          itr2
+	JNE           sealSSE128InnerCipherLoop
+
+	// A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded
+	PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2
+	PADDL T1, B0; PADDL T1, B1; PADDL T1, B2
+	PADDL T2, C1; PADDL T2, C2
+	PADDL T3, D1; PADDL ·sseIncMask<>(SB), T3; PADDL T3, D2
+	PAND  ·polyClampMask<>(SB), A0
+	MOVOU A0, rStore
+	MOVOU B0, sStore
+
+	// Hash
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+	XORQ itr1, itr1
+
+sealSSE128SealHash:
+	// itr1 holds the number of bytes encrypted but not yet hashed
+	CMPQ itr1, $16
+	JB   sealSSE128Seal
+	polyAdd(0(oup))
+	polyMul
+
+	SUBQ $16, itr1
+	ADDQ $16, oup
+
+	JMP sealSSE128SealHash
+
+sealSSE128Seal:
+	CMPQ inl, $16
+	JB   sealSSETail
+	SUBQ $16, inl
+
+	// Load for decryption
+	MOVOU (inp), T0
+	PXOR  T0, A1
+	MOVOU A1, (oup)
+	LEAQ  (1*16)(inp), inp
+	LEAQ  (1*16)(oup), oup
+
+	// Extract for hashing
+	MOVQ   A1, t0
+	PSRLDQ $8, A1
+	MOVQ A1, t1
+	ADDQ   t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2
+	polyMul
+
+	// Shift the stream "left"
+	MOVO B1, A1
+	MOVO C1, B1
+	MOVO D1, C1
+	MOVO A2, D1
+	MOVO B2, A2
+	MOVO C2, B2
+	MOVO D2, C2
+	JMP  sealSSE128Seal
+
+sealSSETail:
+	TESTQ inl, inl
+	JE    sealSSEFinalize
+
+	// We can only load the PT one byte at a time to avoid read after end of buffer
+	MOVQ inl, itr2
+	SHLQ $4, itr2
+	LEAQ ·andMask<>(SB), t0
+	MOVQ inl, itr1
+	LEAQ -1(inp)(inl*1), inp
+	XORQ t2, t2
+	XORQ t3, t3
+	XORQ AX, AX
+
+sealSSETailLoadLoop:
+	SHLQ $8, t2, t3
+	SHLQ $8, t2
+	MOVB (inp), AX
+	XORQ AX, t2
+	LEAQ   -1(inp), inp
+	DECQ   itr1
+	JNE    sealSSETailLoadLoop
+	MOVQ t2, 0+tmpStore
+	MOVQ t3, 8+tmpStore
+	PXOR 0+tmpStore, A1
+	MOVOU  A1, (oup)
+	MOVOU  -16(t0)(itr2*1), T0
+	PAND   T0, A1
+	MOVQ   A1, t0
+	PSRLDQ $8, A1
+	MOVQ   A1, t1
+	ADDQ   t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2
+	polyMul
+
+	ADDQ inl, oup
+
+sealSSEFinalize:
+	// Hash in the buffer lengths
+	ADDQ ad_len+80(FP), acc0
+	ADCQ src_len+56(FP), acc1
+	ADCQ $1, acc2
+	polyMul
+
+	// Final reduce
+	MOVQ    acc0, t0
+	MOVQ    acc1, t1
+	MOVQ    acc2, t2
+	SUBQ    $-5, acc0
+	SBBQ    $-1, acc1
+	SBBQ    $3, acc2
+	CMOVQCS t0, acc0
+	CMOVQCS t1, acc1
+	CMOVQCS t2, acc2
+
+	// Add in the "s" part of the key
+	ADDQ 0+sStore, acc0
+	ADCQ 8+sStore, acc1
+
+	// Finally store the tag at the end of the message
+	MOVQ acc0, (0*8)(oup)
+	MOVQ acc1, (1*8)(oup)
+	RET
+
+// ----------------------------------------------------------------------------
+// ------------------------- AVX2 Code ----------------------------------------
+chacha20Poly1305Seal_AVX2:
+	VZEROUPPER
+	VMOVDQU ·chacha20Constants<>(SB), AA0
+	BYTE    $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x70; BYTE $0x10 // broadcasti128 16(r8), ymm14
+	BYTE    $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x20 // broadcasti128 32(r8), ymm12
+	BYTE    $0xc4; BYTE $0xc2; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x30 // broadcasti128 48(r8), ymm4
+	VPADDD  ·avx2InitMask<>(SB), DD0, DD0
+
+	// Special optimizations, for very short buffers
+	CMPQ inl, $192
+	JBE  seal192AVX2 // 33% faster
+	CMPQ inl, $320
+	JBE  seal320AVX2 // 17% faster
+
+	// For the general key prepare the key first - as a byproduct we have 64 bytes of cipher stream
+	VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3
+	VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3; VMOVDQA BB0, state1StoreAVX2
+	VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3; VMOVDQA CC0, state2StoreAVX2
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD1; VMOVDQA DD0, ctr0StoreAVX2
+	VPADDD  ·avx2IncMask<>(SB), DD1, DD2; VMOVDQA DD1, ctr1StoreAVX2
+	VPADDD  ·avx2IncMask<>(SB), DD2, DD3; VMOVDQA DD2, ctr2StoreAVX2
+	VMOVDQA DD3, ctr3StoreAVX2
+	MOVQ    $10, itr2
+
+sealAVX2IntroLoop:
+	VMOVDQA CC3, tmpStoreAVX2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3)
+	VMOVDQA tmpStoreAVX2, CC3
+	VMOVDQA CC1, tmpStoreAVX2
+	chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1)
+	VMOVDQA tmpStoreAVX2, CC1
+
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $12, DD0, DD0, DD0
+	VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $12, DD1, DD1, DD1
+	VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $12, DD2, DD2, DD2
+	VPALIGNR $4, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $12, DD3, DD3, DD3
+
+	VMOVDQA CC3, tmpStoreAVX2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3)
+	VMOVDQA tmpStoreAVX2, CC3
+	VMOVDQA CC1, tmpStoreAVX2
+	chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1)
+	VMOVDQA tmpStoreAVX2, CC1
+
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $4, DD0, DD0, DD0
+	VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $4, DD1, DD1, DD1
+	VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $4, DD2, DD2, DD2
+	VPALIGNR $12, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $4, DD3, DD3, DD3
+	DECQ     itr2
+	JNE      sealAVX2IntroLoop
+
+	VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3
+	VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3
+	VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3
+	VPADDD ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3
+
+	VPERM2I128 $0x13, CC0, DD0, CC0 // Stream bytes 96 - 127
+	VPERM2I128 $0x02, AA0, BB0, DD0 // The Poly1305 key
+	VPERM2I128 $0x13, AA0, BB0, AA0 // Stream bytes 64 - 95
+
+	// Clamp and store poly key
+	VPAND   ·polyClampMask<>(SB), DD0, DD0
+	VMOVDQA DD0, rsStoreAVX2
+
+	// Hash AD
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+
+	// Can store at least 320 bytes
+	VPXOR   (0*32)(inp), AA0, AA0
+	VPXOR   (1*32)(inp), CC0, CC0
+	VMOVDQU AA0, (0*32)(oup)
+	VMOVDQU CC0, (1*32)(oup)
+
+	VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0
+	VPXOR      (2*32)(inp), AA0, AA0; VPXOR (3*32)(inp), BB0, BB0; VPXOR (4*32)(inp), CC0, CC0; VPXOR (5*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (2*32)(oup); VMOVDQU BB0, (3*32)(oup); VMOVDQU CC0, (4*32)(oup); VMOVDQU DD0, (5*32)(oup)
+	VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0
+	VPXOR      (6*32)(inp), AA0, AA0; VPXOR (7*32)(inp), BB0, BB0; VPXOR (8*32)(inp), CC0, CC0; VPXOR (9*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (6*32)(oup); VMOVDQU BB0, (7*32)(oup); VMOVDQU CC0, (8*32)(oup); VMOVDQU DD0, (9*32)(oup)
+
+	MOVQ $320, itr1
+	SUBQ $320, inl
+	LEAQ 320(inp), inp
+
+	VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, CC3, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, CC3, DD3, DD0
+	CMPQ       inl, $128
+	JBE        sealAVX2SealHash
+
+	VPXOR   (0*32)(inp), AA0, AA0; VPXOR (1*32)(inp), BB0, BB0; VPXOR (2*32)(inp), CC0, CC0; VPXOR (3*32)(inp), DD0, DD0
+	VMOVDQU AA0, (10*32)(oup); VMOVDQU BB0, (11*32)(oup); VMOVDQU CC0, (12*32)(oup); VMOVDQU DD0, (13*32)(oup)
+	SUBQ    $128, inl
+	LEAQ    128(inp), inp
+
+	MOVQ $8, itr1
+	MOVQ $2, itr2
+
+	CMPQ inl, $128
+	JBE  sealAVX2Tail128
+	CMPQ inl, $256
+	JBE  sealAVX2Tail256
+	CMPQ inl, $384
+	JBE  sealAVX2Tail384
+	CMPQ inl, $512
+	JBE  sealAVX2Tail512
+
+	// We have 448 bytes to hash, but main loop hashes 512 bytes at a time - perform some rounds, before the main loop
+	VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3
+	VMOVDQA ctr3StoreAVX2, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3
+	VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2
+
+	VMOVDQA CC3, tmpStoreAVX2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3)
+	VMOVDQA tmpStoreAVX2, CC3
+	VMOVDQA CC1, tmpStoreAVX2
+	chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1)
+	VMOVDQA tmpStoreAVX2, CC1
+
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $12, DD0, DD0, DD0
+	VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $12, DD1, DD1, DD1
+	VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $12, DD2, DD2, DD2
+	VPALIGNR $4, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $12, DD3, DD3, DD3
+
+	VMOVDQA CC3, tmpStoreAVX2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3)
+	VMOVDQA tmpStoreAVX2, CC3
+	VMOVDQA CC1, tmpStoreAVX2
+	chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1)
+	VMOVDQA tmpStoreAVX2, CC1
+
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $4, DD0, DD0, DD0
+	VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $4, DD1, DD1, DD1
+	VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $4, DD2, DD2, DD2
+	VPALIGNR $12, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $4, DD3, DD3, DD3
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+
+	SUBQ $16, oup                  // Adjust the pointer
+	MOVQ $9, itr1
+	JMP  sealAVX2InternalLoopStart
+
+sealAVX2MainLoop:
+	// Load state, increment counter blocks, store the incremented counters
+	VMOVDQU ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3
+	VMOVDQA ctr3StoreAVX2, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3
+	VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2
+	MOVQ    $10, itr1
+
+sealAVX2InternalLoop:
+	polyAdd(0*8(oup))
+	VPADDD  BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	polyMulStage1_AVX2
+	VPXOR   AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	polyMulStage2_AVX2
+	VPADDD  DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR   CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	polyMulStage3_AVX2
+	VMOVDQA CC3, tmpStoreAVX2
+	VPSLLD  $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD  $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD  $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD  $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA tmpStoreAVX2, CC3
+	polyMulReduceStage
+
+sealAVX2InternalLoopStart:
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	polyAdd(2*8(oup))
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	polyMulStage1_AVX2
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyMulStage2_AVX2
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	polyMulStage3_AVX2
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	polyMulReduceStage
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	polyAdd(4*8(oup))
+	LEAQ     (6*8)(oup), oup
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyMulStage1_AVX2
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	polyMulStage2_AVX2
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	polyMulStage3_AVX2
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyMulReduceStage
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3
+	DECQ     itr1
+	JNE      sealAVX2InternalLoop
+
+	VPADDD  ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3
+	VPADDD  state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3
+	VPADDD  state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3
+	VPADDD  ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3
+	VMOVDQA CC3, tmpStoreAVX2
+
+	// We only hashed 480 of the 512 bytes available - hash the remaining 32 here
+	polyAdd(0*8(oup))
+	polyMulAVX2
+	LEAQ       (4*8)(oup), oup
+	VPERM2I128 $0x02, AA0, BB0, CC3; VPERM2I128 $0x13, AA0, BB0, BB0; VPERM2I128 $0x02, CC0, DD0, AA0; VPERM2I128 $0x13, CC0, DD0, CC0
+	VPXOR      (0*32)(inp), CC3, CC3; VPXOR (1*32)(inp), AA0, AA0; VPXOR (2*32)(inp), BB0, BB0; VPXOR (3*32)(inp), CC0, CC0
+	VMOVDQU    CC3, (0*32)(oup); VMOVDQU AA0, (1*32)(oup); VMOVDQU BB0, (2*32)(oup); VMOVDQU CC0, (3*32)(oup)
+	VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0
+	VPXOR      (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup)
+
+	// and here
+	polyAdd(-2*8(oup))
+	polyMulAVX2
+	VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0
+	VPXOR      (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup)
+	VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0
+	VPXOR      (12*32)(inp), AA0, AA0; VPXOR (13*32)(inp), BB0, BB0; VPXOR (14*32)(inp), CC0, CC0; VPXOR (15*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (12*32)(oup); VMOVDQU BB0, (13*32)(oup); VMOVDQU CC0, (14*32)(oup); VMOVDQU DD0, (15*32)(oup)
+	LEAQ       (32*16)(inp), inp
+	SUBQ       $(32*16), inl
+	CMPQ       inl, $512
+	JG         sealAVX2MainLoop
+
+	// Tail can only hash 480 bytes
+	polyAdd(0*8(oup))
+	polyMulAVX2
+	polyAdd(2*8(oup))
+	polyMulAVX2
+	LEAQ 32(oup), oup
+
+	MOVQ $10, itr1
+	MOVQ $0, itr2
+	CMPQ inl, $128
+	JBE  sealAVX2Tail128
+	CMPQ inl, $256
+	JBE  sealAVX2Tail256
+	CMPQ inl, $384
+	JBE  sealAVX2Tail384
+	JMP  sealAVX2Tail512
+
+// ----------------------------------------------------------------------------
+// Special optimization for buffers smaller than 193 bytes
+seal192AVX2:
+	// For up to 192 bytes of ciphertext and 64 bytes for the poly key, we process four blocks
+	VMOVDQA AA0, AA1
+	VMOVDQA BB0, BB1
+	VMOVDQA CC0, CC1
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD1
+	VMOVDQA AA0, AA2
+	VMOVDQA BB0, BB2
+	VMOVDQA CC0, CC2
+	VMOVDQA DD0, DD2
+	VMOVDQA DD1, TT3
+	MOVQ    $10, itr2
+
+sealAVX2192InnerCipherLoop:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR   $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1
+	VPALIGNR   $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR   $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	VPALIGNR   $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1
+	VPALIGNR   $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR   $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1
+	DECQ       itr2
+	JNE        sealAVX2192InnerCipherLoop
+	VPADDD     AA2, AA0, AA0; VPADDD AA2, AA1, AA1
+	VPADDD     BB2, BB0, BB0; VPADDD BB2, BB1, BB1
+	VPADDD     CC2, CC0, CC0; VPADDD CC2, CC1, CC1
+	VPADDD     DD2, DD0, DD0; VPADDD TT3, DD1, DD1
+	VPERM2I128 $0x02, AA0, BB0, TT0
+
+	// Clamp and store poly key
+	VPAND   ·polyClampMask<>(SB), TT0, TT0
+	VMOVDQA TT0, rsStoreAVX2
+
+	// Stream for up to 192 bytes
+	VPERM2I128 $0x13, AA0, BB0, AA0
+	VPERM2I128 $0x13, CC0, DD0, BB0
+	VPERM2I128 $0x02, AA1, BB1, CC0
+	VPERM2I128 $0x02, CC1, DD1, DD0
+	VPERM2I128 $0x13, AA1, BB1, AA1
+	VPERM2I128 $0x13, CC1, DD1, BB1
+
+sealAVX2ShortSeal:
+	// Hash aad
+	MOVQ ad_len+80(FP), itr2
+	CALL polyHashADInternal<>(SB)
+	XORQ itr1, itr1
+
+sealAVX2SealHash:
+	// itr1 holds the number of bytes encrypted but not yet hashed
+	CMPQ itr1, $16
+	JB   sealAVX2ShortSealLoop
+	polyAdd(0(oup))
+	polyMul
+	SUBQ $16, itr1
+	ADDQ $16, oup
+	JMP  sealAVX2SealHash
+
+sealAVX2ShortSealLoop:
+	CMPQ inl, $32
+	JB   sealAVX2ShortTail32
+	SUBQ $32, inl
+
+	// Load for encryption
+	VPXOR   (inp), AA0, AA0
+	VMOVDQU AA0, (oup)
+	LEAQ    (1*32)(inp), inp
+
+	// Now can hash
+	polyAdd(0*8(oup))
+	polyMulAVX2
+	polyAdd(2*8(oup))
+	polyMulAVX2
+	LEAQ (1*32)(oup), oup
+
+	// Shift stream left
+	VMOVDQA BB0, AA0
+	VMOVDQA CC0, BB0
+	VMOVDQA DD0, CC0
+	VMOVDQA AA1, DD0
+	VMOVDQA BB1, AA1
+	VMOVDQA CC1, BB1
+	VMOVDQA DD1, CC1
+	VMOVDQA AA2, DD1
+	VMOVDQA BB2, AA2
+	JMP     sealAVX2ShortSealLoop
+
+sealAVX2ShortTail32:
+	CMPQ    inl, $16
+	VMOVDQA A0, A1
+	JB      sealAVX2ShortDone
+
+	SUBQ $16, inl
+
+	// Load for encryption
+	VPXOR   (inp), A0, T0
+	VMOVDQU T0, (oup)
+	LEAQ    (1*16)(inp), inp
+
+	// Hash
+	polyAdd(0*8(oup))
+	polyMulAVX2
+	LEAQ       (1*16)(oup), oup
+	VPERM2I128 $0x11, AA0, AA0, AA0
+	VMOVDQA    A0, A1
+
+sealAVX2ShortDone:
+	VZEROUPPER
+	JMP sealSSETail
+
+// ----------------------------------------------------------------------------
+// Special optimization for buffers smaller than 321 bytes
+seal320AVX2:
+	// For up to 320 bytes of ciphertext and 64 bytes for the poly key, we process six blocks
+	VMOVDQA AA0, AA1; VMOVDQA BB0, BB1; VMOVDQA CC0, CC1; VPADDD ·avx2IncMask<>(SB), DD0, DD1
+	VMOVDQA AA0, AA2; VMOVDQA BB0, BB2; VMOVDQA CC0, CC2; VPADDD ·avx2IncMask<>(SB), DD1, DD2
+	VMOVDQA BB0, TT1; VMOVDQA CC0, TT2; VMOVDQA DD0, TT3
+	MOVQ    $10, itr2
+
+sealAVX2320InnerCipherLoop:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2
+	DECQ     itr2
+	JNE      sealAVX2320InnerCipherLoop
+
+	VMOVDQA ·chacha20Constants<>(SB), TT0
+	VPADDD  TT0, AA0, AA0; VPADDD TT0, AA1, AA1; VPADDD TT0, AA2, AA2
+	VPADDD  TT1, BB0, BB0; VPADDD TT1, BB1, BB1; VPADDD TT1, BB2, BB2
+	VPADDD  TT2, CC0, CC0; VPADDD TT2, CC1, CC1; VPADDD TT2, CC2, CC2
+	VMOVDQA ·avx2IncMask<>(SB), TT0
+	VPADDD  TT3, DD0, DD0; VPADDD TT0, TT3, TT3
+	VPADDD  TT3, DD1, DD1; VPADDD TT0, TT3, TT3
+	VPADDD  TT3, DD2, DD2
+
+	// Clamp and store poly key
+	VPERM2I128 $0x02, AA0, BB0, TT0
+	VPAND      ·polyClampMask<>(SB), TT0, TT0
+	VMOVDQA    TT0, rsStoreAVX2
+
+	// Stream for up to 320 bytes
+	VPERM2I128 $0x13, AA0, BB0, AA0
+	VPERM2I128 $0x13, CC0, DD0, BB0
+	VPERM2I128 $0x02, AA1, BB1, CC0
+	VPERM2I128 $0x02, CC1, DD1, DD0
+	VPERM2I128 $0x13, AA1, BB1, AA1
+	VPERM2I128 $0x13, CC1, DD1, BB1
+	VPERM2I128 $0x02, AA2, BB2, CC1
+	VPERM2I128 $0x02, CC2, DD2, DD1
+	VPERM2I128 $0x13, AA2, BB2, AA2
+	VPERM2I128 $0x13, CC2, DD2, BB2
+	JMP        sealAVX2ShortSeal
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 128 bytes of ciphertext
+sealAVX2Tail128:
+	// Need to decrypt up to 128 bytes - prepare two blocks
+	// If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed
+	// If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed
+	VMOVDQA ·chacha20Constants<>(SB), AA0
+	VMOVDQA state1StoreAVX2, BB0
+	VMOVDQA state2StoreAVX2, CC0
+	VMOVDQA ctr3StoreAVX2, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD0
+	VMOVDQA DD0, DD1
+
+sealAVX2Tail128LoopA:
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+sealAVX2Tail128LoopB:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0)
+	polyAdd(0(oup))
+	polyMul
+	VPALIGNR $4, BB0, BB0, BB0
+	VPALIGNR $8, CC0, CC0, CC0
+	VPALIGNR $12, DD0, DD0, DD0
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0)
+	polyAdd(16(oup))
+	polyMul
+	LEAQ     32(oup), oup
+	VPALIGNR $12, BB0, BB0, BB0
+	VPALIGNR $8, CC0, CC0, CC0
+	VPALIGNR $4, DD0, DD0, DD0
+	DECQ     itr1
+	JG       sealAVX2Tail128LoopA
+	DECQ     itr2
+	JGE      sealAVX2Tail128LoopB
+
+	VPADDD ·chacha20Constants<>(SB), AA0, AA1
+	VPADDD state1StoreAVX2, BB0, BB1
+	VPADDD state2StoreAVX2, CC0, CC1
+	VPADDD DD1, DD0, DD1
+
+	VPERM2I128 $0x02, AA1, BB1, AA0
+	VPERM2I128 $0x02, CC1, DD1, BB0
+	VPERM2I128 $0x13, AA1, BB1, CC0
+	VPERM2I128 $0x13, CC1, DD1, DD0
+	JMP        sealAVX2ShortSealLoop
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 256 bytes of ciphertext
+sealAVX2Tail256:
+	// Need to decrypt up to 256 bytes - prepare two blocks
+	// If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed
+	// If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed
+	VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA ·chacha20Constants<>(SB), AA1
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA state1StoreAVX2, BB1
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA state2StoreAVX2, CC1
+	VMOVDQA ctr3StoreAVX2, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD1
+	VMOVDQA DD0, TT1
+	VMOVDQA DD1, TT2
+
+sealAVX2Tail256LoopA:
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+sealAVX2Tail256LoopB:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	polyAdd(0(oup))
+	polyMul
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0)
+	polyAdd(16(oup))
+	polyMul
+	LEAQ     32(oup), oup
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1
+	DECQ     itr1
+	JG       sealAVX2Tail256LoopA
+	DECQ     itr2
+	JGE      sealAVX2Tail256LoopB
+
+	VPADDD     ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1
+	VPADDD     state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1
+	VPADDD     state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1
+	VPADDD     TT1, DD0, DD0; VPADDD TT2, DD1, DD1
+	VPERM2I128 $0x02, AA0, BB0, TT0
+	VPERM2I128 $0x02, CC0, DD0, TT1
+	VPERM2I128 $0x13, AA0, BB0, TT2
+	VPERM2I128 $0x13, CC0, DD0, TT3
+	VPXOR      (0*32)(inp), TT0, TT0; VPXOR (1*32)(inp), TT1, TT1; VPXOR (2*32)(inp), TT2, TT2; VPXOR (3*32)(inp), TT3, TT3
+	VMOVDQU    TT0, (0*32)(oup); VMOVDQU TT1, (1*32)(oup); VMOVDQU TT2, (2*32)(oup); VMOVDQU TT3, (3*32)(oup)
+	MOVQ       $128, itr1
+	LEAQ       128(inp), inp
+	SUBQ       $128, inl
+	VPERM2I128 $0x02, AA1, BB1, AA0
+	VPERM2I128 $0x02, CC1, DD1, BB0
+	VPERM2I128 $0x13, AA1, BB1, CC0
+	VPERM2I128 $0x13, CC1, DD1, DD0
+
+	JMP sealAVX2SealHash
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 384 bytes of ciphertext
+sealAVX2Tail384:
+	// Need to decrypt up to 384 bytes - prepare two blocks
+	// If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed
+	// If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed
+	VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2
+	VMOVDQA ctr3StoreAVX2, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2
+	VMOVDQA DD0, TT1; VMOVDQA DD1, TT2; VMOVDQA DD2, TT3
+
+sealAVX2Tail384LoopA:
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+sealAVX2Tail384LoopB:
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	polyAdd(0(oup))
+	polyMul
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2
+	chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0)
+	polyAdd(16(oup))
+	polyMul
+	LEAQ     32(oup), oup
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2
+	DECQ     itr1
+	JG       sealAVX2Tail384LoopA
+	DECQ     itr2
+	JGE      sealAVX2Tail384LoopB
+
+	VPADDD     ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2
+	VPADDD     state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2
+	VPADDD     state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2
+	VPADDD     TT1, DD0, DD0; VPADDD TT2, DD1, DD1; VPADDD TT3, DD2, DD2
+	VPERM2I128 $0x02, AA0, BB0, TT0
+	VPERM2I128 $0x02, CC0, DD0, TT1
+	VPERM2I128 $0x13, AA0, BB0, TT2
+	VPERM2I128 $0x13, CC0, DD0, TT3
+	VPXOR      (0*32)(inp), TT0, TT0; VPXOR (1*32)(inp), TT1, TT1; VPXOR (2*32)(inp), TT2, TT2; VPXOR (3*32)(inp), TT3, TT3
+	VMOVDQU    TT0, (0*32)(oup); VMOVDQU TT1, (1*32)(oup); VMOVDQU TT2, (2*32)(oup); VMOVDQU TT3, (3*32)(oup)
+	VPERM2I128 $0x02, AA1, BB1, TT0
+	VPERM2I128 $0x02, CC1, DD1, TT1
+	VPERM2I128 $0x13, AA1, BB1, TT2
+	VPERM2I128 $0x13, CC1, DD1, TT3
+	VPXOR      (4*32)(inp), TT0, TT0; VPXOR (5*32)(inp), TT1, TT1; VPXOR (6*32)(inp), TT2, TT2; VPXOR (7*32)(inp), TT3, TT3
+	VMOVDQU    TT0, (4*32)(oup); VMOVDQU TT1, (5*32)(oup); VMOVDQU TT2, (6*32)(oup); VMOVDQU TT3, (7*32)(oup)
+	MOVQ       $256, itr1
+	LEAQ       256(inp), inp
+	SUBQ       $256, inl
+	VPERM2I128 $0x02, AA2, BB2, AA0
+	VPERM2I128 $0x02, CC2, DD2, BB0
+	VPERM2I128 $0x13, AA2, BB2, CC0
+	VPERM2I128 $0x13, CC2, DD2, DD0
+
+	JMP sealAVX2SealHash
+
+// ----------------------------------------------------------------------------
+// Special optimization for the last 512 bytes of ciphertext
+sealAVX2Tail512:
+	// Need to decrypt up to 512 bytes - prepare two blocks
+	// If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed
+	// If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed
+	VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3
+	VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3
+	VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3
+	VMOVDQA ctr3StoreAVX2, DD0
+	VPADDD  ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3
+	VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2
+
+sealAVX2Tail512LoopA:
+	polyAdd(0(oup))
+	polyMul
+	LEAQ 16(oup), oup
+
+sealAVX2Tail512LoopB:
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	polyAdd(0*8(oup))
+	polyMulAVX2
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	polyAdd(2*8(oup))
+	polyMulAVX2
+	LEAQ     (4*8)(oup), oup
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	VPADDD   BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3
+	VPXOR    AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3
+	VPSHUFB  ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3
+	VPADDD   DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3
+	VPXOR    CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3
+	VMOVDQA  CC3, tmpStoreAVX2
+	VPSLLD   $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0
+	VPSLLD   $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1
+	VPSLLD   $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2
+	VPSLLD   $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3
+	VMOVDQA  tmpStoreAVX2, CC3
+	VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3
+	VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3
+	VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3
+
+	DECQ itr1
+	JG   sealAVX2Tail512LoopA
+	DECQ itr2
+	JGE  sealAVX2Tail512LoopB
+
+	VPADDD     ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3
+	VPADDD     state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3
+	VPADDD     state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3
+	VPADDD     ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3
+	VMOVDQA    CC3, tmpStoreAVX2
+	VPERM2I128 $0x02, AA0, BB0, CC3
+	VPXOR      (0*32)(inp), CC3, CC3
+	VMOVDQU    CC3, (0*32)(oup)
+	VPERM2I128 $0x02, CC0, DD0, CC3
+	VPXOR      (1*32)(inp), CC3, CC3
+	VMOVDQU    CC3, (1*32)(oup)
+	VPERM2I128 $0x13, AA0, BB0, CC3
+	VPXOR      (2*32)(inp), CC3, CC3
+	VMOVDQU    CC3, (2*32)(oup)
+	VPERM2I128 $0x13, CC0, DD0, CC3
+	VPXOR      (3*32)(inp), CC3, CC3
+	VMOVDQU    CC3, (3*32)(oup)
+
+	VPERM2I128 $0x02, AA1, BB1, AA0
+	VPERM2I128 $0x02, CC1, DD1, BB0
+	VPERM2I128 $0x13, AA1, BB1, CC0
+	VPERM2I128 $0x13, CC1, DD1, DD0
+	VPXOR      (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup)
+
+	VPERM2I128 $0x02, AA2, BB2, AA0
+	VPERM2I128 $0x02, CC2, DD2, BB0
+	VPERM2I128 $0x13, AA2, BB2, CC0
+	VPERM2I128 $0x13, CC2, DD2, DD0
+	VPXOR      (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0
+	VMOVDQU    AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup)
+
+	MOVQ       $384, itr1
+	LEAQ       384(inp), inp
+	SUBQ       $384, inl
+	VPERM2I128 $0x02, AA3, BB3, AA0
+	VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0
+	VPERM2I128 $0x13, AA3, BB3, CC0
+	VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0
+
+	JMP sealAVX2SealHash

+ 81 - 0
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go

@@ -0,0 +1,81 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package chacha20poly1305
+
+import (
+	"encoding/binary"
+
+	"golang.org/x/crypto/chacha20"
+	"golang.org/x/crypto/internal/alias"
+	"golang.org/x/crypto/internal/poly1305"
+)
+
+func writeWithPadding(p *poly1305.MAC, b []byte) {
+	p.Write(b)
+	if rem := len(b) % 16; rem != 0 {
+		var buf [16]byte
+		padLen := 16 - rem
+		p.Write(buf[:padLen])
+	}
+}
+
+func writeUint64(p *poly1305.MAC, n int) {
+	var buf [8]byte
+	binary.LittleEndian.PutUint64(buf[:], uint64(n))
+	p.Write(buf[:])
+}
+
+func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {
+	ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
+	ciphertext, tag := out[:len(plaintext)], out[len(plaintext):]
+	if alias.InexactOverlap(out, plaintext) {
+		panic("chacha20poly1305: invalid buffer overlap")
+	}
+
+	var polyKey [32]byte
+	s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce)
+	s.XORKeyStream(polyKey[:], polyKey[:])
+	s.SetCounter(1) // set the counter to 1, skipping 32 bytes
+	s.XORKeyStream(ciphertext, plaintext)
+
+	p := poly1305.New(&polyKey)
+	writeWithPadding(p, additionalData)
+	writeWithPadding(p, ciphertext)
+	writeUint64(p, len(additionalData))
+	writeUint64(p, len(plaintext))
+	p.Sum(tag[:0])
+
+	return ret
+}
+
+func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+	tag := ciphertext[len(ciphertext)-16:]
+	ciphertext = ciphertext[:len(ciphertext)-16]
+
+	var polyKey [32]byte
+	s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce)
+	s.XORKeyStream(polyKey[:], polyKey[:])
+	s.SetCounter(1) // set the counter to 1, skipping 32 bytes
+
+	p := poly1305.New(&polyKey)
+	writeWithPadding(p, additionalData)
+	writeWithPadding(p, ciphertext)
+	writeUint64(p, len(additionalData))
+	writeUint64(p, len(ciphertext))
+
+	ret, out := sliceForAppend(dst, len(ciphertext))
+	if alias.InexactOverlap(out, ciphertext) {
+		panic("chacha20poly1305: invalid buffer overlap")
+	}
+	if !p.Verify(tag) {
+		for i := range out {
+			out[i] = 0
+		}
+		return nil, errOpen
+	}
+
+	s.XORKeyStream(out, ciphertext)
+	return ret, nil
+}

+ 16 - 0
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go

@@ -0,0 +1,16 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !amd64 || !gc || purego
+// +build !amd64 !gc purego
+
+package chacha20poly1305
+
+func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte {
+	return c.sealGeneric(dst, nonce, plaintext, additionalData)
+}
+
+func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+	return c.openGeneric(dst, nonce, ciphertext, additionalData)
+}

+ 86 - 0
vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go

@@ -0,0 +1,86 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package chacha20poly1305
+
+import (
+	"crypto/cipher"
+	"errors"
+
+	"golang.org/x/crypto/chacha20"
+)
+
+type xchacha20poly1305 struct {
+	key [KeySize]byte
+}
+
+// NewX returns a XChaCha20-Poly1305 AEAD that uses the given 256-bit key.
+//
+// XChaCha20-Poly1305 is a ChaCha20-Poly1305 variant that takes a longer nonce,
+// suitable to be generated randomly without risk of collisions. It should be
+// preferred when nonce uniqueness cannot be trivially ensured, or whenever
+// nonces are randomly generated.
+func NewX(key []byte) (cipher.AEAD, error) {
+	if len(key) != KeySize {
+		return nil, errors.New("chacha20poly1305: bad key length")
+	}
+	ret := new(xchacha20poly1305)
+	copy(ret.key[:], key)
+	return ret, nil
+}
+
+func (*xchacha20poly1305) NonceSize() int {
+	return NonceSizeX
+}
+
+func (*xchacha20poly1305) Overhead() int {
+	return Overhead
+}
+
+func (x *xchacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
+	if len(nonce) != NonceSizeX {
+		panic("chacha20poly1305: bad nonce length passed to Seal")
+	}
+
+	// XChaCha20-Poly1305 technically supports a 64-bit counter, so there is no
+	// size limit. However, since we reuse the ChaCha20-Poly1305 implementation,
+	// the second half of the counter is not available. This is unlikely to be
+	// an issue because the cipher.AEAD API requires the entire message to be in
+	// memory, and the counter overflows at 256 GB.
+	if uint64(len(plaintext)) > (1<<38)-64 {
+		panic("chacha20poly1305: plaintext too large")
+	}
+
+	c := new(chacha20poly1305)
+	hKey, _ := chacha20.HChaCha20(x.key[:], nonce[0:16])
+	copy(c.key[:], hKey)
+
+	// The first 4 bytes of the final nonce are unused counter space.
+	cNonce := make([]byte, NonceSize)
+	copy(cNonce[4:12], nonce[16:24])
+
+	return c.seal(dst, cNonce[:], plaintext, additionalData)
+}
+
+func (x *xchacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+	if len(nonce) != NonceSizeX {
+		panic("chacha20poly1305: bad nonce length passed to Open")
+	}
+	if len(ciphertext) < 16 {
+		return nil, errOpen
+	}
+	if uint64(len(ciphertext)) > (1<<38)-48 {
+		panic("chacha20poly1305: ciphertext too large")
+	}
+
+	c := new(chacha20poly1305)
+	hKey, _ := chacha20.HChaCha20(x.key[:], nonce[0:16])
+	copy(c.key[:], hKey)
+
+	// The first 4 bytes of the final nonce are unused counter space.
+	cNonce := make([]byte, NonceSize)
+	copy(cNonce[4:12], nonce[16:24])
+
+	return c.open(dst, cNonce[:], ciphertext, additionalData)
+}

+ 93 - 0
vendor/golang.org/x/crypto/hkdf/hkdf.go

@@ -0,0 +1,93 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package hkdf implements the HMAC-based Extract-and-Expand Key Derivation
+// Function (HKDF) as defined in RFC 5869.
+//
+// HKDF is a cryptographic key derivation function (KDF) with the goal of
+// expanding limited input keying material into one or more cryptographically
+// strong secret keys.
+package hkdf // import "golang.org/x/crypto/hkdf"
+
+import (
+	"crypto/hmac"
+	"errors"
+	"hash"
+	"io"
+)
+
+// Extract generates a pseudorandom key for use with Expand from an input secret
+// and an optional independent salt.
+//
+// Only use this function if you need to reuse the extracted key with multiple
+// Expand invocations and different context values. Most common scenarios,
+// including the generation of multiple keys, should use New instead.
+func Extract(hash func() hash.Hash, secret, salt []byte) []byte {
+	if salt == nil {
+		salt = make([]byte, hash().Size())
+	}
+	extractor := hmac.New(hash, salt)
+	extractor.Write(secret)
+	return extractor.Sum(nil)
+}
+
+type hkdf struct {
+	expander hash.Hash
+	size     int
+
+	info    []byte
+	counter byte
+
+	prev []byte
+	buf  []byte
+}
+
+func (f *hkdf) Read(p []byte) (int, error) {
+	// Check whether enough data can be generated
+	need := len(p)
+	remains := len(f.buf) + int(255-f.counter+1)*f.size
+	if remains < need {
+		return 0, errors.New("hkdf: entropy limit reached")
+	}
+	// Read any leftover from the buffer
+	n := copy(p, f.buf)
+	p = p[n:]
+
+	// Fill the rest of the buffer
+	for len(p) > 0 {
+		f.expander.Reset()
+		f.expander.Write(f.prev)
+		f.expander.Write(f.info)
+		f.expander.Write([]byte{f.counter})
+		f.prev = f.expander.Sum(f.prev[:0])
+		f.counter++
+
+		// Copy the new batch into p
+		f.buf = f.prev
+		n = copy(p, f.buf)
+		p = p[n:]
+	}
+	// Save leftovers for next run
+	f.buf = f.buf[n:]
+
+	return need, nil
+}
+
+// Expand returns a Reader, from which keys can be read, using the given
+// pseudorandom key and optional context info, skipping the extraction step.
+//
+// The pseudorandomKey should have been generated by Extract, or be a uniformly
+// random or pseudorandom cryptographically strong key. See RFC 5869, Section
+// 3.3. Most common scenarios will want to use New instead.
+func Expand(hash func() hash.Hash, pseudorandomKey, info []byte) io.Reader {
+	expander := hmac.New(hash, pseudorandomKey)
+	return &hkdf{expander, expander.Size(), info, 1, nil, nil}
+}
+
+// New returns a Reader, from which keys can be read, using the given hash,
+// secret, salt and context info. Salt and info can be nil.
+func New(hash func() hash.Hash, secret, salt, info []byte) io.Reader {
+	prk := Extract(hash, secret, salt)
+	return Expand(hash, prk, info)
+}

+ 3 - 6
vendor/golang.org/x/oauth2/google/default.go

@@ -8,7 +8,6 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
 	"net/http"
 	"os"
 	"path/filepath"
@@ -142,10 +141,8 @@ func FindDefaultCredentialsWithParams(ctx context.Context, params CredentialsPar
 
 	// Second, try a well-known file.
 	filename := wellKnownFile()
-	if creds, err := readCredentialsFile(ctx, filename, params); err == nil {
-		return creds, nil
-	} else if !os.IsNotExist(err) {
-		return nil, fmt.Errorf("google: error getting credentials using well-known file (%v): %v", filename, err)
+	if b, err := os.ReadFile(filename); err == nil {
+		return CredentialsFromJSONWithParams(ctx, b, params)
 	}
 
 	// Third, if we're on a Google App Engine standard first generation runtime (<= Go 1.9)
@@ -231,7 +228,7 @@ func wellKnownFile() string {
 }
 
 func readCredentialsFile(ctx context.Context, filename string, params CredentialsParams) (*Credentials, error) {
-	b, err := ioutil.ReadFile(filename)
+	b, err := os.ReadFile(filename)
 	if err != nil {
 		return nil, err
 	}

+ 1 - 1
vendor/golang.org/x/oauth2/internal/oauth2.go

@@ -14,7 +14,7 @@ import (
 
 // ParseKey converts the binary contents of a private key file
 // to an *rsa.PrivateKey. It detects whether the private key is in a
-// PEM container or not. If so, it extracts the the private key
+// PEM container or not. If so, it extracts the private key
 // from PEM container before conversion. It only supports PEM
 // containers with no passphrase.
 func ParseKey(key []byte) (*rsa.PrivateKey, error) {

+ 50 - 10
vendor/golang.org/x/oauth2/internal/token.go

@@ -55,12 +55,18 @@ type Token struct {
 }
 
 // tokenJSON is the struct representing the HTTP response from OAuth2
-// providers returning a token in JSON form.
+// providers returning a token or error in JSON form.
+// https://datatracker.ietf.org/doc/html/rfc6749#section-5.1
 type tokenJSON struct {
 	AccessToken  string         `json:"access_token"`
 	TokenType    string         `json:"token_type"`
 	RefreshToken string         `json:"refresh_token"`
 	ExpiresIn    expirationTime `json:"expires_in"` // at least PayPal returns string, while most return number
+	// error fields
+	// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
+	ErrorCode        string `json:"error"`
+	ErrorDescription string `json:"error_description"`
+	ErrorURI         string `json:"error_uri"`
 }
 
 func (e *tokenJSON) expiry() (t time.Time) {
@@ -236,21 +242,29 @@ func doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) {
 	if err != nil {
 		return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
 	}
-	if code := r.StatusCode; code < 200 || code > 299 {
-		return nil, &RetrieveError{
-			Response: r,
-			Body:     body,
-		}
+
+	failureStatus := r.StatusCode < 200 || r.StatusCode > 299
+	retrieveError := &RetrieveError{
+		Response: r,
+		Body:     body,
+		// attempt to populate error detail below
 	}
 
 	var token *Token
 	content, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
 	switch content {
 	case "application/x-www-form-urlencoded", "text/plain":
+		// some endpoints return a query string
 		vals, err := url.ParseQuery(string(body))
 		if err != nil {
-			return nil, err
+			if failureStatus {
+				return nil, retrieveError
+			}
+			return nil, fmt.Errorf("oauth2: cannot parse response: %v", err)
 		}
+		retrieveError.ErrorCode = vals.Get("error")
+		retrieveError.ErrorDescription = vals.Get("error_description")
+		retrieveError.ErrorURI = vals.Get("error_uri")
 		token = &Token{
 			AccessToken:  vals.Get("access_token"),
 			TokenType:    vals.Get("token_type"),
@@ -265,8 +279,14 @@ func doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) {
 	default:
 		var tj tokenJSON
 		if err = json.Unmarshal(body, &tj); err != nil {
-			return nil, err
+			if failureStatus {
+				return nil, retrieveError
+			}
+			return nil, fmt.Errorf("oauth2: cannot parse json: %v", err)
 		}
+		retrieveError.ErrorCode = tj.ErrorCode
+		retrieveError.ErrorDescription = tj.ErrorDescription
+		retrieveError.ErrorURI = tj.ErrorURI
 		token = &Token{
 			AccessToken:  tj.AccessToken,
 			TokenType:    tj.TokenType,
@@ -276,17 +296,37 @@ func doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) {
 		}
 		json.Unmarshal(body, &token.Raw) // no error checks for optional fields
 	}
+	// according to spec, servers should respond status 400 in error case
+	// https://www.rfc-editor.org/rfc/rfc6749#section-5.2
+	// but some unorthodox servers respond 200 in error case
+	if failureStatus || retrieveError.ErrorCode != "" {
+		return nil, retrieveError
+	}
 	if token.AccessToken == "" {
 		return nil, errors.New("oauth2: server response missing access_token")
 	}
 	return token, nil
 }
 
+// mirrors oauth2.RetrieveError
 type RetrieveError struct {
-	Response *http.Response
-	Body     []byte
+	Response         *http.Response
+	Body             []byte
+	ErrorCode        string
+	ErrorDescription string
+	ErrorURI         string
 }
 
 func (r *RetrieveError) Error() string {
+	if r.ErrorCode != "" {
+		s := fmt.Sprintf("oauth2: %q", r.ErrorCode)
+		if r.ErrorDescription != "" {
+			s += fmt.Sprintf(" %q", r.ErrorDescription)
+		}
+		if r.ErrorURI != "" {
+			s += fmt.Sprintf(" %q", r.ErrorURI)
+		}
+		return s
+	}
 	return fmt.Sprintf("oauth2: cannot fetch token: %v\nResponse: %s", r.Response.Status, r.Body)
 }

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác