+ "Backend not available. BackendId: ",
+ static_cast<int>(token.backendId));
+};
+
+GStore* Decider::tryBackend(CryptoBackend backend)
+{
+ switch(backend) {
+ case CryptoBackend::OpenSSL:
+ return &m_swStore;
+ case CryptoBackend::TrustZone:
+#ifdef TZ_BACKEND_ENABLED
+ try {
+ LogDebug("Trying to open TA session...");
+ TZ::Internals::TrustZoneContext::Instance();
+ LogDebug("...succeeded. Selecting TZ backend.");
+ return &m_tzStore;
+ } catch (const Exc::Crypto::InternalError& e) {
+ LogDebug("...failed.");
+ }
+#endif
+ default:
+ break;
+ }
+ return nullptr;
+}
+
+/*
+ * operation encrypted type extractable backend
+ * ----------------------------------------------
+ * import FALSE binary - TZ/SW
+ * skey FALSE TZ/SW
+ * skey TRUE SW
+ * akey - SW
+ * cert - SW
+ * TRUE binary - TZ
+ * skey FALSE TZ
+ * skey TRUE NONE
+ * akey - NONE
+ * cert - NONE
+ * generate - binary FALSE TZ/SW
+ * - binary TRUE SW
+ * - cert - NONE
+ * - skey FALSE TZ/SW
+ * - skey TRUE SW
+ * - akey FALSE TZ/SW
+ * - akey TRUE SW
+ */
+std::deque<CryptoBackend> Decider::getCompatibleBackends(DataType data,
+ const Policy &policy,
+ bool import,
+ bool encrypted)
+{
+ std::deque<CryptoBackend> backends;
+
+ auto addSW = [&]{
+ if (policy.backend != CKM::PolicyBackend::FORCE_HARDWARE)
+ backends.push_back(CryptoBackend::OpenSSL);
+ };
+
+ auto addTZ = [&]{
+#ifdef TZ_BACKEND_ENABLED
+ if (policy.backend != CKM::PolicyBackend::FORCE_SOFTWARE)
+ backends.push_front(CryptoBackend::TrustZone);
+#endif
+ };
+
+ if (import) {
+ if (!encrypted)
+ addSW();
+
+ if (data.isBinaryData() || (data.isSKey() && !policy.extractable))
+ addTZ();
+ } else { // generate/derive
+ assert(!encrypted);
+
+ if (!data.isCertificate() && !data.isChainCert()) {
+ addSW();
+
+ if (!policy.extractable)
+ addTZ();
+ }
+ }
+ return backends;