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