xref: /aosp_15_r20/tools/security/remote_provisioning/hwtrust/cxxbridge/hwtrust.cpp (revision d9ecfb0f4d734c9ce41cde8ac4d585b094fd4222)
1 #include <hwtrust/hwtrust.h>
2 #include <hwtrust/lib.rs.h>
3 
4 using android::base::Error;
5 using android::base::Result;
6 
7 namespace hwtrust {
8 
convertKind(DiceChain::Kind kind)9 rust::DiceChainKind convertKind(DiceChain::Kind kind) {
10   switch (kind) {
11     case DiceChain::Kind::kVsr13:
12       return rust::DiceChainKind::Vsr13;
13     case DiceChain::Kind::kVsr14:
14       return rust::DiceChainKind::Vsr14;
15     case DiceChain::Kind::kVsr15:
16       return rust::DiceChainKind::Vsr15;
17     case DiceChain::Kind::kVsr16:
18       return rust::DiceChainKind::Vsr16;
19   }
20 }
21 
22 // The public API hides all rust deps from clients, so we end up with opaque, boxed types. This
23 // class standardizes the syntax for dealing with these types. How to...
24 // ...define a boxed opaque type:     struct BoxedFoo : Boxed<Foo, BoxedFoo> {};
25 // ...construct an object:            auto foo = BoxedFoo::moveFrom(boxed);
26 // ...dereference the inner object:   **foo;
27 template <typename BoxedT, typename DerivedT>
28 class Boxed {
29 public:
Boxed(::rust::Box<BoxedT> b)30   Boxed(::rust::Box<BoxedT> b) : box_(std::move(b)) {}
31 
moveFrom(::rust::Box<BoxedT> & b)32   static std::unique_ptr<DerivedT> moveFrom(::rust::Box<BoxedT>& b) {
33     return std::make_unique<DerivedT>(std::move(b));
34   }
35 
operator *() const36   const BoxedT &operator*() const noexcept { return *box_; }
operator *()37   BoxedT &operator*() noexcept { return *box_; }
38 
39 private:
40   ::rust::Box<BoxedT> box_;
41 };
42 
43 // Definition of the forward-declared boxed types.
44 struct BoxedDiceChain : Boxed<rust::DiceChain, BoxedDiceChain> {};
45 struct BoxedCsr : Boxed<rust::Csr, BoxedCsr> {};
46 
47 
48 // Define to satisfy unique_ptr.
~DiceChain()49 DiceChain::~DiceChain() {}
50 
DiceChain(std::unique_ptr<BoxedDiceChain> chain,size_t size)51 DiceChain::DiceChain(std::unique_ptr<BoxedDiceChain> chain, size_t size) noexcept
52       : chain_(std::move(chain)), size_(size) {}
53 
Verify(const std::vector<uint8_t> & chain,DiceChain::Kind kind,bool allow_any_mode,std::string_view instance)54 Result<DiceChain> DiceChain::Verify(
55   const std::vector<uint8_t>& chain, DiceChain::Kind kind, bool allow_any_mode,
56   std::string_view instance) noexcept {
57   rust::DiceChainKind chainKind = convertKind(kind);
58   auto res = rust::VerifyDiceChain(
59     {chain.data(), chain.size()}, chainKind, allow_any_mode, instance.data());
60   if (!res.error.empty()) {
61       return Error() << static_cast<std::string>(res.error);
62   }
63   return DiceChain(BoxedDiceChain::moveFrom(res.chain), res.len);
64 }
65 
CosePublicKeys() const66 Result<std::vector<std::vector<uint8_t>>> DiceChain::CosePublicKeys() const noexcept {
67   std::vector<std::vector<uint8_t>> result;
68   for (auto i = 0; i < size_; ++i) {
69     auto key = rust::GetDiceChainPublicKey(**chain_, i);
70     if (key.empty()) {
71       return Error() << "Failed to get public key from chain entry " << i;
72     }
73     result.emplace_back(key.begin(), key.end());
74   }
75   return result;
76 }
77 
IsProper() const78 bool DiceChain::IsProper() const noexcept {
79   return rust::IsDiceChainProper(**chain_);
80 }
81 
82 // Define with a full definition of BoxedCsr to satisfy unique_ptr.
~Csr()83 Csr::~Csr() {}
84 
Csr(std::unique_ptr<BoxedCsr> csr,DiceChain::Kind kind,std::string_view instance)85 Csr::Csr(std::unique_ptr<BoxedCsr> csr, DiceChain::Kind kind, std::string_view instance) noexcept
86     : mCsr(std::move(csr)), mKind(kind), mInstance(instance.data()) {}
87 
validate(const std::vector<uint8_t> & request,DiceChain::Kind kind,bool allowAnyMode,std::string_view instance)88 Result<Csr> Csr::validate(const std::vector<uint8_t>& request, DiceChain::Kind kind, bool allowAnyMode,
89     std::string_view instance) noexcept {
90     rust::DiceChainKind chainKind = convertKind(kind);
91     auto result = rust::validateCsr(
92         {request.data(), request.size()}, chainKind, allowAnyMode, instance.data());
93     if (!result.error.empty()) {
94         return Error() << static_cast<std::string>(result.error);
95     }
96     return Csr(BoxedCsr::moveFrom(result.csr), kind, instance);
97 }
98 
getDiceChain() const99 Result<DiceChain> Csr::getDiceChain() const noexcept {
100     auto result = rust::getDiceChainFromCsr(**mCsr);
101     if (!result.error.empty()) {
102         return Error() << static_cast<std::string>(result.error);
103     }
104   return DiceChain(BoxedDiceChain::moveFrom(result.chain), result.len);
105 }
106 
107 } // namespace hwtrust
108