blob: 96f236d5f77ed96c67403e3fa6ddcb988c65fbba [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_CRYPTORECOVERY_RECOVERY_CRYPTO_UTIL_H_
#define CRYPTOHOME_CRYPTORECOVERY_RECOVERY_CRYPTO_UTIL_H_
#include <string>
#include <brillo/secure_blob.h>
#include <chromeos/cbor/values.h>
namespace cryptohome {
namespace cryptorecovery {
// AEAD-encrypted payload.
struct AeadPayload {
// AES-GCM tag for encryption.
brillo::SecureBlob tag;
// AES-GCM iv for encryption.
brillo::SecureBlob iv;
// Additional authentication data, passed in clear. Serialized in cbor.
brillo::SecureBlob associated_data;
// Encrypted plain text. Plain text is serialized in cbor.
brillo::SecureBlob cipher_text;
};
// HSM Payload is created at onboarding and contains all the data that are
// persisted on a chromebook and will be eventually used for recovery.
using HsmPayload = AeadPayload;
// Recovery Request Payload is created during recovery flow.
// `associated_data` contains data from `HsmPayload`, request metadata (RMD),
// and epoch public key (G*r).
using RequestPayload = AeadPayload;
// 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.
using ResponsePayload = AeadPayload;
// !!! DO NOT MODIFY !!!
// The enum values below are exchanged with the server and must be synced with
// the server/HSM implementation (or the other party will not be able to decrypt
// the data). Type of the `cryptohome_user` field sent in `OnboardingMetadata`.
enum class UserType {
kUnknown = 0,
kGaiaId = 1,
};
// `OnboardingMetadata` contains essential information that needs to be
// available during the Recovery workflow. This information is used by the
// Recovery Service and may be recorded in the Ledger.
struct OnboardingMetadata {
UserType cryptohome_user_type = UserType::kUnknown;
// Format of `cryptohome_user` is determined by `cryptohome_user_type` enum.
std::string cryptohome_user;
// Unique ID tied to the user's cryptohome on the device
std::string device_user_id;
std::string board_name;
std::string model_name;
// Generated anew after each successful recovery, hex-encoded sha-256 hash
// string.
std::string recovery_id;
};
// `associated_data` for the HSM payload.
// `publisher_pub_key` and `channel_pub_key` are elliptic curve points
// encoded in OpenSSL octet form (a binary encoding of the EC_POINT
// structure as defined in RFC5480).
// TODO(mslus): exact format of rsa_public_key used for TPM 1.2 is
// to be defined.
struct HsmAssociatedData {
// G*u, one of the keys that will be used for HSM payload decryption.
brillo::SecureBlob publisher_pub_key;
// G*s, one of the keys that will be used for Request payload decryption.
brillo::SecureBlob channel_pub_key;
// The key (X.509 SubjectPublicKeyInfo structure in DER) sent to HSM so that
// it can validate Request payload, used only for TPM 1.2.
brillo::SecureBlob rsa_public_key;
// The metadata generated during the Onboarding workflow on a Chromebook
// (OMD).
OnboardingMetadata onboarding_meta_data;
};
// Plain text for the HSM payload.
// `dealer_pub_key` is an elliptic curve point encoded in OpenSSL octet form (a
// binary encoding of the EC_POINT structure as defined in RFC5480).
// `mediator_share` and `key_auth_value` are BIGNUMs encoded in big-endian
// form.
struct HsmPlainText {
// Secret share of the Mediator (b1).
brillo::SecureBlob mediator_share;
// Key generated on Chromebook, to be sent to the Mediator service (G*a).
brillo::SecureBlob dealer_pub_key;
// Additional secret to seal the destination share. Used for TPM 1.2 only.
brillo::SecureBlob key_auth_value;
};
// Data used to prove user's authentication to the Recovery Service.
struct AuthClaim {
// Access token with reauth scope.
std::string gaia_access_token;
// A short-lived token, it's validity will be verified by the Recovery
// Service.
std::string gaia_reauth_proof_token;
};
// `RequestMetadata` includes any information the Chromebook needs logged in the
// ledger. Different auth_claim types can be supported by using the
// schema_version to distinguish them.
struct RequestMetadata {
AuthClaim auth_claim;
UserType requestor_user_id_type = UserType::kUnknown;
// Format of `requestor_user_id` is determined by `requestor_user_id_type`
// enum.
std::string requestor_user_id;
};
// `EpochMetadata` includes any information the HSM needs to compute the Epoch
// beacon, and which will be logged into the ledger.
struct EpochMetadata {
// Cbor map containing epoch metadata. This map is passed to the recovery
// server without being read by the client.
cbor::Value meta_data_cbor;
EpochMetadata() = default;
EpochMetadata(EpochMetadata const& other)
: meta_data_cbor(other.meta_data_cbor.Clone()) {}
EpochMetadata& operator=(const EpochMetadata& other) {
if (this != &other) {
meta_data_cbor = other.meta_data_cbor.Clone();
}
return *this;
}
};
// `associated_data` for the Request payload.
struct RecoveryRequestAssociatedData {
// HSM payload.
HsmPayload hsm_payload;
// The metadata generated during the Recovery flow on a Chromebook (RMD).
RequestMetadata request_meta_data;
// The metadata generated on the Reverse Proxy, and retrieved by the
// Chromebook from the Recovery Service when it obtains the Epoch Beacon.
EpochMetadata epoch_meta_data;
// Current epoch beacon value (G*r).
brillo::SecureBlob epoch_pub_key;
// Salt used in the derivation of request payload encryption key.
brillo::SecureBlob request_payload_salt;
};
// Plain text for the Request payload.
// `ephemeral_pub_inv_key` is an elliptic curve point encoded in OpenSSL octet
// form (a binary encoding of the EC_POINT structure as defined in RFC5480).
struct RecoveryRequestPlainText {
// Ephemeral inverse key (G*-x) that is added to mediator DH (G*ab1) by the
// Mediator service.
brillo::SecureBlob ephemeral_pub_inv_key;
};
// RecoveryRequest is the request sent to the HSM server.
struct RecoveryRequest {
// The AEAD-encrypted payload.
brillo::SecureBlob request_payload;
// The RSA signature of the AEAD-encrypted payload using SHA-256.
// It's an optional field, used only on TPM 1.2 devices.
brillo::SecureBlob rsa_signature;
};
// Metadata to be sent back from the HSM to the Chromebook, empty so far.
struct HsmMetaData {};
// `associated_data` for the Response payload.
struct HsmResponseAssociatedData {
// Salt used in the derivation of response payload encryption key.
brillo::SecureBlob response_payload_salt;
// The metadata generated by HSM.
HsmMetaData hsm_meta_data;
};
// Plain text for the Response payload.
// `dealer_pub_key` and `mediated_point` are elliptic curve points encoded in
// OpenSSL octet form (a binary encoding of the EC_POINT structure as defined in
// RFC5480). `key_auth_value` is BIGNUM encoded in big-endian form.
struct HsmResponsePlainText {
// Mediated mediator share (b1) sent back to the Chromebook.
brillo::SecureBlob mediated_point;
// Key generated on Chromebook, that was used for mediation (G*a).
brillo::SecureBlob dealer_pub_key;
// Additional secret to seal the destination share. Used for TPM 1.2 only.
brillo::SecureBlob key_auth_value;
};
// RecoveryResponse is the cbor response to a RecoveryRequest.
struct RecoveryResponse {
// The AEAD-encrypted payload.
ResponsePayload response_payload;
// Numeric error code.
int error_code = 0;
// Error message.
std::string error_string;
};
} // namespace cryptorecovery
} // namespace cryptohome
#endif // CRYPTOHOME_CRYPTORECOVERY_RECOVERY_CRYPTO_UTIL_H_