Commit 53a80b56 authored by Maksim Moskvitin's avatar Maksim Moskvitin Committed by Commit Bot

Add SecureBox implementation

SecureBox provides a set of simple interfaces for performing encryptions
and decryptions, by using a public key owned by the recipient and/or a
secret shared by the sender and the recipient.

Bug: 1101813
Change-Id: I9ced4c91a8d31b0b395096ad6045b5075df899f5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2279971
Commit-Queue: Maksim Moskvitin <mmoskvitin@google.com>
Reviewed-by: default avatarDavid Benjamin <davidben@chromium.org>
Reviewed-by: default avatarMikel Astiz <mastiz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#791049}
parent 80d56521
...@@ -520,6 +520,7 @@ source_set("unit_tests") { ...@@ -520,6 +520,7 @@ source_set("unit_tests") {
"nigori/nigori_unittest.cc", "nigori/nigori_unittest.cc",
"protocol/proto_enum_conversions_unittest.cc", "protocol/proto_enum_conversions_unittest.cc",
"protocol/proto_value_conversions_unittest.cc", "protocol/proto_value_conversions_unittest.cc",
"trusted_vault/securebox_unittest.cc",
"trusted_vault/standalone_trusted_vault_client_unittest.cc", "trusted_vault/standalone_trusted_vault_client_unittest.cc",
] ]
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
static_library("trusted_vault") { static_library("trusted_vault") {
sources = [ sources = [
"securebox.cc",
"securebox.h",
"standalone_trusted_vault_backend.cc", "standalone_trusted_vault_backend.cc",
"standalone_trusted_vault_backend.h", "standalone_trusted_vault_backend.h",
"standalone_trusted_vault_client.cc", "standalone_trusted_vault_client.cc",
...@@ -17,5 +19,7 @@ static_library("trusted_vault") { ...@@ -17,5 +19,7 @@ static_library("trusted_vault") {
"//components/os_crypt", "//components/os_crypt",
"//components/signin/public/identity_manager", "//components/signin/public/identity_manager",
"//components/sync/protocol", "//components/sync/protocol",
"//crypto",
"//third_party/boringssl",
] ]
} }
...@@ -3,4 +3,6 @@ include_rules = [ ...@@ -3,4 +3,6 @@ include_rules = [
"+components/signin/public", "+components/signin/public",
"+components/sync/driver", "+components/sync/driver",
"+components/sync/protocol", "+components/sync/protocol",
"+crypto",
"+third_party/boringssl",
] ]
\ No newline at end of file
This diff is collapsed.
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SYNC_TRUSTED_VAULT_SECUREBOX_H_
#define COMPONENTS_SYNC_TRUSTED_VAULT_SECUREBOX_H_
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include "base/containers/span.h"
#include "base/optional.h"
#include "third_party/boringssl/src/include/openssl/base.h"
namespace crypto {
class OpenSSLErrStackTracer;
} // namespace crypto
namespace syncer {
class SecureBoxPublicKey {
public:
// Creates public key given a X9.62 formatted NIST P-256 point as |key_bytes|
// (e.g. by the output of SecureBoxPublicKey::ExportToBytes()). Returns
// nullptr if point format isn't correct or it doesn't represent a valid P-256
// point.
static std::unique_ptr<SecureBoxPublicKey> CreateByImport(
base::span<const uint8_t> key_bytes);
// |key| must be a valid NIST P-256 key with filled public key. This method
// shouldn't be used outside internal SecureBox implementation.
static std::unique_ptr<SecureBoxPublicKey> CreateInternal(
bssl::UniquePtr<EC_KEY> key,
const crypto::OpenSSLErrStackTracer& err_tracer);
SecureBoxPublicKey(const SecureBoxPublicKey& other) = delete;
SecureBoxPublicKey& operator=(const SecureBoxPublicKey& other) = delete;
~SecureBoxPublicKey();
// Returns a X9.62 formatted NIST P-256 point.
std::vector<uint8_t> ExportToBytes() const;
// Encrypts |payload| according to SecureBox v2 spec (go/securebox2):
// 1. Key material is P-256 ECDH key derived from |key_| and randomly
// generated P-256 key pair, concatenated with |shared_secret|.
// 2. Encryption key is derived from key material using HKDF-SHA256.
// 3. |payload| is encrypted using AES-128-GCM, using random 96-bit nonce and
// given |header|.
// |shared_secret|, |header| and |payload| may be empty.
std::vector<uint8_t> Encrypt(base::span<const uint8_t> shared_secret,
base::span<const uint8_t> header,
base::span<const uint8_t> payload) const;
private:
// |key| must be a valid NIST P-256 key with filled public key.
SecureBoxPublicKey(bssl::UniquePtr<EC_KEY> key,
const crypto::OpenSSLErrStackTracer& err_tracer);
bssl::UniquePtr<EC_KEY> key_;
};
class SecureBoxPrivateKey {
public:
// Creates private key given NIST P-256 scalar in padded big-endian format
// (e.g. by the output of SecureBoxPrivateKey::ExportToBytes()). Returns
// nullptr if P-256 key can't be decoded from |key_bytes| or its format is
// incorrect.
static std::unique_ptr<SecureBoxPrivateKey> CreateByImport(
base::span<const uint8_t> key_bytes);
// |key| must be a valid NIST P-256 key with filled private and public key.
// This method shouldn't be used outside internal SecureBox implementation.
static std::unique_ptr<SecureBoxPrivateKey> CreateInternal(
bssl::UniquePtr<EC_KEY> key,
const crypto::OpenSSLErrStackTracer& err_tracer);
SecureBoxPrivateKey(const SecureBoxPrivateKey& other) = delete;
SecureBoxPrivateKey& operator=(const SecureBoxPrivateKey& other) = delete;
~SecureBoxPrivateKey();
// Returns NIST P-256 scalar in padded big-endian format.
std::vector<uint8_t> ExportToBytes() const;
// Decrypts |encrypted_payload| according to SecureBox v2 spec (see
// SecureBoxPublicKey::Encrypt()). Returns nullopt if payload was encrypted
// with different parameters or |encrypted_payload| isn't a valid SecureBox
// encrypted data.
base::Optional<std::vector<uint8_t>> Decrypt(
base::span<const uint8_t> shared_secret,
base::span<const uint8_t> header,
base::span<const uint8_t> encrypted_payload) const;
private:
// |key| must be a valid NIST P-256 key with filled private and public key.
explicit SecureBoxPrivateKey(bssl::UniquePtr<EC_KEY> key,
const crypto::OpenSSLErrStackTracer& err_tracer);
bssl::UniquePtr<EC_KEY> key_;
};
class SecureBoxKeyPair {
public:
// Generates new random key pair. Never returns nullptr.
static std::unique_ptr<SecureBoxKeyPair> GenerateRandom();
// Creates key pair given NIST P-256 scalar in padded big-endian format
// (e.g. by the output of SecureBoxPrivateKey::ExportToBytes()). Returns
// nullptr if P-256 key can't be decoded from |private_key_bytes| or its
// format is incorrect.
static std::unique_ptr<SecureBoxKeyPair> CreateByPrivateKeyImport(
base::span<uint8_t> private_key_bytes);
SecureBoxKeyPair(const SecureBoxKeyPair& other) = delete;
SecureBoxKeyPair& operator=(const SecureBoxKeyPair& other) = delete;
~SecureBoxKeyPair();
const SecureBoxPrivateKey& private_key() const { return *private_key_; }
const SecureBoxPublicKey& public_key() const { return *public_key_; }
private:
SecureBoxKeyPair(bssl::UniquePtr<EC_KEY> private_ec_key,
const crypto::OpenSSLErrStackTracer& err_tracer);
std::unique_ptr<SecureBoxPrivateKey> private_key_;
std::unique_ptr<SecureBoxPublicKey> public_key_;
};
} // namespace syncer
#endif // COMPONENTS_SYNC_TRUSTED_VAULT_SECUREBOX_H_
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment