blob: 4a18a7ca1fcafbebd7644dfc80d6cb87e140d7d2 [file] [log] [blame]
// Copyright 2021 The Chromium OS 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 CRYPTOHOME_CRYPTO_FAKE_RECOVERY_MEDIATOR_CRYPTO_H_
#define CRYPTOHOME_CRYPTO_FAKE_RECOVERY_MEDIATOR_CRYPTO_H_
#include <memory>
#include <brillo/secure_blob.h>
#include "cryptohome/crypto/elliptic_curve.h"
#include "cryptohome/crypto/recovery_crypto.h"
namespace cryptohome {
// Cryptographic operations for fake mediator for cryptohome recovery.
// Recovery mechanism involves dealer, publisher, mediator and destination.
// The mediator is an external service that is invoked during the recovery
// process to perform mediation of an encrypted mediator share. The
// functionality of mediator should be implemented on the server and here it is
// implemented for testing purposes only.
class FakeRecoveryMediatorCrypto {
public:
// Fake HSM response. Contains response associated data AD3 = {kav, HMD}
// (where kav is Key Auth Value and HMD is HSM Metadata) and plain text
// response PT3 = {dealer_pub_key, mediated_share} encrypted with
// DH of epoch and channel_pub_key.
struct ResponsePayload {
brillo::SecureBlob tag;
brillo::SecureBlob iv;
brillo::SecureBlob associated_data;
brillo::SecureBlob cipher_text;
};
// Creates instance. Returns nullptr if error occurred.
static std::unique_ptr<FakeRecoveryMediatorCrypto> Create();
// Returns hardcoded fake mediator public key for encrypting mediator share.
// Do not use this key in production!
// Returns false if error occurred.
static bool GetFakeMediatorPublicKey(brillo::SecureBlob* mediator_pub_key);
// Returns hardcoded fake mediator private key for decrypting mediator share.
// Do not use this key in production!
// Returns false if error occurred.
static bool GetFakeMediatorPrivateKey(brillo::SecureBlob* mediator_priv_key);
// Returns hardcoded fake epoch public key for encrypting request payload.
// Do not use this key in production!
// Returns false if error occurred.
static bool GetFakeEpochPublicKey(brillo::SecureBlob* epoch_pub_key);
// Returns hardcoded fake epoch private key for decrypting request payload.
// Do not use this key in production!
// Returns false if error occurred.
static bool GetFakeEpochPrivateKey(brillo::SecureBlob* epoch_priv_key);
// Performs mediation. Returns `mediated_publisher_pub_key`, which is
// `publisher_pub_key` multiplied by secret `mediator_share` that only
// mediator can decrypt from `encrypted_mediator_share`. Returns false if
// error occurred. It is expected that `encrypted_mediator_share` is encrypted
// to `mediator_priv_key`. Formula:
// mediator_share = Decrypt(encrypted_mediator_share)
// mediated_publisher_pub_key = publisher_pub_key * mediator_share
bool Mediate(
const brillo::SecureBlob& mediator_priv_key,
const brillo::SecureBlob& publisher_pub_key,
const RecoveryCrypto::EncryptedMediatorShare& encrypted_mediator_share,
brillo::SecureBlob* mediated_publisher_pub_key) const;
// Receives `request_payload`, performs mediation and generates response
// payload. This function consist of the following steps:
// 1. Deserialize `channel_pub_key` from `hsm_aead_ad` in
// `request_payload.associated_data`.
// 2. Perform DH(`epoch_priv_key`, channel_pub_key), decrypt
// `cipher_text` (CT2) from `request_payload`.
// 3. Extract `hsm_payload` from `request_payload`.
// 4. Do `MediateHsmPayload` with `hsm_payload` and keys (`epoch_pub_key`,
// `epoch_priv_key`, `mediator_priv_key`).
bool MediateRequestPayload(
const brillo::SecureBlob& epoch_pub_key,
const brillo::SecureBlob& epoch_priv_key,
const brillo::SecureBlob& mediator_priv_key,
const RecoveryCrypto::RequestPayload& request_payload,
ResponsePayload* response_payload) const;
private:
// Constructor is private. Use Create method to instantiate.
explicit FakeRecoveryMediatorCrypto(EllipticCurve ec);
// Receives `hsm_payload`, performs mediation and generates response payload.
// This function consist of the following steps:
// 1. Deserialize publisher_pub_key from `associated_data` in `hsm_payload`.
// 2. Perform DH(`mediator_priv_key`, publisher_pub_key), decrypt
// `cipher_text` from `hsm_payload` and get mediator_share and
// dealer_pub_key
// 3. Construct mediated_share = G * dealer_priv_key * mediator_share +
// `ephemeral_pub_inv_key`.
// 4. Serialize response payload associated_data and plain_text
// 5. Generate encryption key as KDF(combine(epoch_pub_key,
// ECDH(epoch_priv_key, channel_pub_key)))
// 6. Encrypt plain_text and generate `response_payload`
bool MediateHsmPayload(const brillo::SecureBlob& mediator_priv_key,
const brillo::SecureBlob& epoch_pub_key,
const brillo::SecureBlob& epoch_priv_key,
const brillo::SecureBlob& ephemeral_pub_inv_key,
const RecoveryCrypto::HsmPayload& hsm_payload,
ResponsePayload* response_payload) const;
// Decrypts `mediator_share` using `mediator_priv_key` from
// `encrypted_mediator_share`. Returns false if error occurred.
bool DecryptMediatorShare(
const brillo::SecureBlob& mediator_priv_key,
const RecoveryCrypto::EncryptedMediatorShare& encrypted_mediator_share,
brillo::SecureBlob* mediator_share) const;
// Decrypt `cipher_text` from `hsm_payload' using provided
// `mediator_priv_key`.
bool DecryptHsmPayloadPlainText(const brillo::SecureBlob& mediator_priv_key,
const RecoveryCrypto::HsmPayload& hsm_payload,
brillo::SecureBlob* plain_text) const;
// Decrypt `cipher_text` from `request_payload' using provided
// `epoch_priv_key` and store the result in `plain_text`.
bool DecryptRequestPayloadPlainText(
const brillo::SecureBlob& epoch_priv_key,
const RecoveryCrypto::RequestPayload& request_payload,
brillo::SecureBlob* plain_text) const;
// Extract `hsm_payload` from associated data of `request_payload'.
bool ExtractHsmPayload(const RecoveryCrypto::RequestPayload& request_payload,
RecoveryCrypto::HsmPayload* hsm_payload) const;
EllipticCurve ec_;
};
} // namespace cryptohome
#endif // CRYPTOHOME_CRYPTO_FAKE_RECOVERY_MEDIATOR_CRYPTO_H_