blob: 7c2125572a64bcdafed3e46d7bfbee786c9d321b [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2013 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
5#ifndef QUICHE_QUIC_CORE_CRYPTO_P256_KEY_EXCHANGE_H_
6#define QUICHE_QUIC_CORE_CRYPTO_P256_KEY_EXCHANGE_H_
7
8#include <cstdint>
vasilvv872e7a32019-03-12 16:42:44 -07009#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050010
vasilvv778cad32020-10-08 12:43:32 -070011#include "absl/strings/string_view.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050012#include "third_party/boringssl/src/include/openssl/base.h"
QUICHE team5be974e2020-12-29 18:35:24 -050013#include "quic/core/crypto/key_exchange.h"
14#include "quic/platform/api/quic_export.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050015
16namespace quic {
17
QUICHE teamfe1aca62019-03-14 13:39:01 -070018// P256KeyExchange implements a SynchronousKeyExchange using elliptic-curve
QUICHE teama6ef0a62019-03-07 20:34:33 -050019// Diffie-Hellman on NIST P-256.
QUICHE teamfe1aca62019-03-14 13:39:01 -070020class QUIC_EXPORT_PRIVATE P256KeyExchange : public SynchronousKeyExchange {
QUICHE teama6ef0a62019-03-07 20:34:33 -050021 public:
22 ~P256KeyExchange() override;
23
QUICHE teamfe1aca62019-03-14 13:39:01 -070024 // New generates a private key and then creates new key-exchange object.
25 static std::unique_ptr<P256KeyExchange> New();
26
27 // New creates a new key-exchange object from a private key. If |private_key|
28 // is invalid, nullptr is returned.
vasilvv778cad32020-10-08 12:43:32 -070029 static std::unique_ptr<P256KeyExchange> New(absl::string_view private_key);
QUICHE teama6ef0a62019-03-07 20:34:33 -050030
QUICHE teamfe1aca62019-03-14 13:39:01 -070031 // NewPrivateKey returns a private key, suitable for passing to |New|.
QUICHE teama6ef0a62019-03-07 20:34:33 -050032 // If |NewPrivateKey| can't generate a private key, it returns an empty
33 // string.
vasilvvc48c8712019-03-11 13:38:16 -070034 static std::string NewPrivateKey();
QUICHE teama6ef0a62019-03-07 20:34:33 -050035
QUICHE teamfe1aca62019-03-14 13:39:01 -070036 // SynchronousKeyExchange interface.
vasilvv778cad32020-10-08 12:43:32 -070037 bool CalculateSharedKeySync(absl::string_view peer_public_value,
QUICHE teamfe1aca62019-03-14 13:39:01 -070038 std::string* shared_key) const override;
vasilvv778cad32020-10-08 12:43:32 -070039 absl::string_view public_value() const override;
QUICHE teamfe1aca62019-03-14 13:39:01 -070040 QuicTag type() const override { return kP256; }
QUICHE teama6ef0a62019-03-07 20:34:33 -050041
42 private:
43 enum {
44 // A P-256 field element consists of 32 bytes.
45 kP256FieldBytes = 32,
46 // A P-256 point in uncompressed form consists of 0x04 (to denote
47 // that the point is uncompressed) followed by two, 32-byte field
48 // elements.
49 kUncompressedP256PointBytes = 1 + 2 * kP256FieldBytes,
50 // The first byte in an uncompressed P-256 point.
51 kUncompressedECPointForm = 0x04,
52 };
53
54 // P256KeyExchange wraps |private_key|, and expects |public_key| consists of
55 // |kUncompressedP256PointBytes| bytes.
56 P256KeyExchange(bssl::UniquePtr<EC_KEY> private_key,
57 const uint8_t* public_key);
58 P256KeyExchange(const P256KeyExchange&) = delete;
59 P256KeyExchange& operator=(const P256KeyExchange&) = delete;
60
61 bssl::UniquePtr<EC_KEY> private_key_;
62 // The public key stored as an uncompressed P-256 point.
63 uint8_t public_key_[kUncompressedP256PointBytes];
64};
65
66} // namespace quic
67
68#endif // QUICHE_QUIC_CORE_CRYPTO_P256_KEY_EXCHANGE_H_