// Copyright 2018 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. // Pinweaver specific model to facilitate fuzzing. #ifndef __FUZZ_PINWEAVER_MODEL_H #define __FUZZ_PINWEAVER_MODEL_H #include #include #include #define HIDE_EC_STDLIB #include "fuzz/cr50_fuzz.pb.h" #include "fuzz/mem_hash_tree.h" #include "fuzz/span.h" #include "include/pinweaver.h" #include "include/pinweaver_types.h" // Provides enough state tracking to send valid PinWeaver requests. This is // necessary because of the authentication dependent fields used by the Merkle // tree such as HMACs and a set of sibling path hashes that must be correct to // reach some parts of the PinWeaver code. class PinweaverModel { public: PinweaverModel(); void SendBuffer(fuzz::span buffer); // Converts the logical representation of a request used in fuzzing into bytes // that can be processed by the pinweaver code for fuzzing. size_t SerializeRequest(const fuzz::pinweaver::Request& pinweaver, fuzz::span buffer) const; // Executes a request in the form of a fuzz::pinweaver::Request proto, and // updates the model, so that future requests will be valid. uint32_t ApplyRequest(const fuzz::pinweaver::Request& pinweaver, fuzz::span buffer); // Clears any state. This shoudl be called at the beginning of each fuzzing // iteration. void Reset(); private: static constexpr uint8_t kNullRootHash[PW_HASH_SIZE] = {}; struct LeafData { std::vector wrapped_data; std::array low_entropy_secret; std::array reset_secret; }; // Functions for retrieving the current state of the metadata. void GetHmac(const std::string& fuzzer_hmac, uint64_t label, fuzz::span hmac) const; size_t CopyMetadata(uint64_t label, const LeafData& leaf_data, unimported_leaf_data_t* unimported_leaf_data, fuzz::span buffer) const; size_t GetMetadata(uint64_t label, unimported_leaf_data_t* unimported_leaf_data, fuzz::span buffer) const; size_t GetPath(const std::string& fuzzer_hashes, uint64_t label, fuzz::span path_hashes) const; // Store copies of the root hash of the Merkle tree, and label of the leaf // associated with a request so that valid get log requests can be generated. void LogRootHash(fuzz::span root_hash, uint64_t label); // Retrieve a root hash from the log at the given index. fuzz::span GetRootHashFromLog(size_t index) const; // Retrieve a leaf label from the log at the given index. uint64_t GetLabelFromLog(size_t index) const; // Helper functions used by SerializePinweaver to convert size_t SerializeResetTree(const fuzz::pinweaver::Request& pinweaver, fuzz::span buffer) const; size_t SerializeInsertLeaf(const fuzz::pinweaver::Request& pinweaver, fuzz::span buffer) const; size_t SerializeRemoveLeaf(const fuzz::pinweaver::Request& pinweaver, fuzz::span buffer) const; size_t SerializeTryAuth(const fuzz::pinweaver::Request& pinweaver, fuzz::span buffer) const; size_t SerializeResetAuth(const fuzz::pinweaver::Request& pinweaver, fuzz::span buffer) const; size_t SerializeGetLog(const fuzz::pinweaver::Request& pinweaver, fuzz::span buffer) const; size_t SerializeLogReplay(const fuzz::pinweaver::Request& pinweaver, fuzz::span buffer) const; // Updates the metadata storage for a particular leaf. |leaf_data| is only // required for insert operations so the metadata, low_entropy_secret, // and reset_secret for the leaf can be retrieved to generate valid // authentication requests. void UpdateMetadata(uint64_t label, const pw_response_header_t& header, const unimported_leaf_data_t* unimported_leaf_data, size_t unimported_leaf_data_length, const LeafData* leaf_data); // Helper functions for updating the state when responses are received. void ApplyResetTree(); void ApplyInsertLeaf(const fuzz::pinweaver::Request& pinweaver, const pw_response_t& response, const LeafData* leaf_data); void ApplyRemoveLeaf(const fuzz::pinweaver::Request& pinweaver, const pw_response_t& response); void ApplyTryAuth(const fuzz::pinweaver::Request& pinweaver, const pw_response_t& response); void ApplyResetAuth(const fuzz::pinweaver::Request& pinweaver, const pw_response_t& response); merkle_tree_t merkle_tree_; MemHashTree mem_hash_tree_; std::deque, uint64_t>> root_history_; std::unordered_map leaf_metadata_; }; #endif // __FUZZ_PINWEAVER_MODEL_H