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