xref: /aosp_15_r20/external/cronet/components/nacl/loader/nacl_validation_query.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2013 The Chromium Authors
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 COMPONENTS_NACL_LOADER_NACL_VALIDATION_QUERY_H_
6 #define COMPONENTS_NACL_LOADER_NACL_VALIDATION_QUERY_H_
7 
8 #include <stddef.h>
9 
10 #include <string>
11 
12 #include "base/memory/raw_ptr.h"
13 #include "base/strings/string_piece.h"
14 #include "crypto/hmac.h"
15 
16 struct NaClValidationCache;
17 class NaClValidationDB;
18 class NaClValidationQuery;
19 
20 class NaClValidationQueryContext {
21  public:
22   NaClValidationQueryContext(NaClValidationDB* db,
23                              const std::string& profile_key,
24                              const std::string& nacl_version);
25 
26   NaClValidationQuery* CreateQuery();
27 
28  private:
29   raw_ptr<NaClValidationDB> db_;
30 
31   // A key used by HMAC that is specific to this installation of Chrome.
32   std::string profile_key_;
33 
34   // Bytes indicating the "version" of the validator being used.  This is used
35   // to implicitly invalidate the cache - changing the version will change the
36   // hashes that are produced.
37   std::string nacl_version_;
38 };
39 
40 class NaClValidationQuery {
41  public:
42   // SHA256 digest size.
43   static const size_t kDigestLength = 32;
44 
45   NaClValidationQuery(NaClValidationDB* db, const std::string& profile_key);
46 
47   NaClValidationQuery(const NaClValidationQuery&) = delete;
48   NaClValidationQuery& operator=(const NaClValidationQuery&) = delete;
49 
50   void AddData(const char* data, size_t length);
51   void AddData(const unsigned char* data, size_t length);
52   void AddData(const base::StringPiece& data);
53 
54   int QueryKnownToValidate();
55 
56   void SetKnownToValidate();
57 
58  private:
59   enum QueryState {
60     READY,
61     GET_CALLED,
62     SET_CALLED
63   };
64 
65   // The HMAC interface currently does not support incremental signing.  To work
66   // around this, each piece of data is signed and the signature is added to a
67   // buffer.  If there is not enough space in the buffer to accommodate new
68   // data, the buffer contents are signed and the new signature replaces the
69   // contents of the buffer.  CompressBuffer performs this operation.  In
70   // affect, a hash tree is constructed to emulate incremental signing.
71   void CompressBuffer();
72 
73   // Track the state of the query to detect suspicious method calls.
74   QueryState state_;
75 
76   crypto::HMAC hasher_;
77   raw_ptr<NaClValidationDB> db_;
78 
79   // The size of buffer_ is a somewhat arbitrary choice.  It needs to be at
80   // at least kDigestLength * 2, but it can be arbitrarily large.  In practice
81   // there are 4 calls to AddData (version, architechture, cpu features, and
82   // code), so 4 times digest length means the buffer will not need to be
83   // compressed as an intermediate step in the expected use cases.
84   char buffer_[kDigestLength * 4];
85   size_t buffer_length_;
86 };
87 
88 // Create a validation cache interface for use by sel_ldr.
89 struct NaClValidationCache* CreateValidationCache(
90     NaClValidationDB* db, const std::string& profile_key,
91     const std::string& nacl_version);
92 
93 #endif  // COMPONENTS_NACL_LOADER_NACL_VALIDATION_QUERY_H_
94