blob: bc92d5fc18402f37895881b33802bc3b90d70e6b [file] [log] [blame]
Bence Békybac04052022-04-07 15:44:29 -04001// Copyright (c) 2022 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
bnce5642f32022-04-11 13:45:33 -07005#ifndef QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_CONFIG_H_
6#define QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_CONFIG_H_
Bence Békybac04052022-04-07 15:44:29 -04007
vasilvvdaa2fda2022-04-11 14:08:36 -07008#include "openssl/aes.h"
Bence Békybac04052022-04-07 15:44:29 -04009#include "quiche/quic/core/quic_types.h"
10#include "quiche/quic/platform/api/quic_export.h"
11
12namespace quic {
13
martinduke77084d52022-04-07 12:27:31 -070014inline constexpr uint8_t kNumLoadBalancerConfigs = 3;
Bence Békybac04052022-04-07 15:44:29 -040015inline constexpr uint8_t kLoadBalancerKeyLen = 16;
16// Regardless of key length, the AES block size is always 16 Bytes.
17inline constexpr uint8_t kLoadBalancerBlockSize = 16;
18// The spec says nonces can be 18 bytes, but 16 lets it be a uint128.
19inline constexpr uint8_t kLoadBalancerMaxNonceLen = 16;
20inline constexpr uint8_t kLoadBalancerMinNonceLen = 4;
martinduke77084d52022-04-07 12:27:31 -070021inline constexpr uint8_t kNumLoadBalancerCryptoPasses = 4;
Bence Békybac04052022-04-07 15:44:29 -040022
23// This the base class for QUIC-LB configuration. It contains configuration
24// elements usable by both encoders (servers) and decoders (load balancers).
25// Confusingly, it is called "LoadBalancerConfig" because it pertains to objects
26// that both servers and load balancers use to interact with each other.
27class QUIC_EXPORT_PRIVATE LoadBalancerConfig {
28 public:
29 // This factory function initializes an encrypted LoadBalancerConfig and
30 // returns it in absl::optional, which is empty if the config is invalid.
31 // config_id: The first two bits of the Connection Id. Must be no larger than
32 // 2.
33 // server_id_len: Expected length of the server ids associated with this
34 // config. Must be greater than 0 and less than 16.
35 // nonce_len: Length of the nonce. Must be at least 4 and no larger than 16.
36 // Further the server_id_len + nonce_len must be no larger than 19.
37 // key: The encryption key must be 16B long.
38 static absl::optional<LoadBalancerConfig> Create(const uint8_t config_id,
39 const uint8_t server_id_len,
40 const uint8_t nonce_len,
41 const absl::string_view key);
42
43 // Creates an unencrypted config.
44 static absl::optional<LoadBalancerConfig> CreateUnencrypted(
45 const uint8_t config_id, const uint8_t server_id_len,
46 const uint8_t nonce_len);
47
48 // Handles one pass of 4-pass encryption. Encoder and decoder use of this
49 // function varies substantially, so they are not implemented here.
martinduke76b4dae2022-04-13 11:11:09 -070050 // Returns false if the config is not encrypted, or if |target| isn't long
51 // enough.
52 ABSL_MUST_USE_RESULT bool EncryptionPass(absl::Span<uint8_t> target,
Bence Békybac04052022-04-07 15:44:29 -040053 const uint8_t index) const;
54 // Use the key to do a block encryption, which is used both in all cases of
55 // encrypted configs. Returns false if there's no key.
56 ABSL_MUST_USE_RESULT bool BlockEncrypt(
57 const uint8_t plaintext[kLoadBalancerBlockSize],
58 uint8_t ciphertext[kLoadBalancerBlockSize]) const;
59 // Returns false if the config does not require block decryption.
60 ABSL_MUST_USE_RESULT bool BlockDecrypt(
61 const uint8_t ciphertext[kLoadBalancerBlockSize],
62 uint8_t plaintext[kLoadBalancerBlockSize]) const;
63
64 uint8_t config_id() const { return config_id_; }
65 uint8_t server_id_len() const { return server_id_len_; }
66 uint8_t nonce_len() const { return nonce_len_; }
martinduke77084d52022-04-07 12:27:31 -070067 // Returns length of all but the first octet.
68 uint8_t plaintext_len() const { return server_id_len_ + nonce_len_; }
69 // Returns length of the entire connection ID.
70 uint8_t total_len() const { return server_id_len_ + nonce_len_ + 1; }
Bence Békybac04052022-04-07 15:44:29 -040071 bool IsEncrypted() const { return key_.has_value(); }
72
73 private:
74 // Constructor is private because it doesn't validate input.
75 LoadBalancerConfig(uint8_t config_id, uint8_t server_id_len,
76 uint8_t nonce_len, absl::string_view key);
77
78 uint8_t config_id_;
79 uint8_t server_id_len_;
80 uint8_t nonce_len_;
81 // All Connection ID encryption and decryption uses the AES_encrypt function
82 // at root, so there is a single key for all of it. This is empty if the
83 // config is not encrypted.
84 absl::optional<AES_KEY> key_;
85 // The one exception is that when total_len == 16, connection ID decryption
86 // uses AES_decrypt. The bytes that comprise the key are the same, but
87 // AES_decrypt requires an AES_KEY that is initialized differently. In all
88 // other cases, block_decrypt_key_ is empty.
89 absl::optional<AES_KEY> block_decrypt_key_;
90};
91
92} // namespace quic
93
bnce5642f32022-04-11 13:45:33 -070094#endif // QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_CONFIG_H_