[libcamera-devel,10/11] libcamera: ipa_manager: Verify IPA module signature

Message ID 20200404015624.30440-11-laurent.pinchart@ideasonboard.com
State Superseded
Headers show
Series
  • Sign IPA modules instead of checking their advertised license
Related show

Commit Message

Laurent Pinchart April 4, 2020, 1:56 a.m. UTC
Decide whether to isolate the IPA module using the module signature
instead of its license.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/libcamera/include/ipa_manager.h |  2 ++
 src/libcamera/include/ipa_module.h  |  2 --
 src/libcamera/ipa_manager.cpp       | 22 +++++++++++++++++++++-
 src/libcamera/ipa_module.cpp        | 25 -------------------------
 4 files changed, 23 insertions(+), 28 deletions(-)

Comments

Niklas Söderlund April 7, 2020, 8:37 p.m. UTC | #1
Hi Laurent,

Thanks for your patch.

On 2020-04-04 04:56:23 +0300, Laurent Pinchart wrote:
> Decide whether to isolate the IPA module using the module signature
> instead of its license.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>

> ---
>  src/libcamera/include/ipa_manager.h |  2 ++
>  src/libcamera/include/ipa_module.h  |  2 --
>  src/libcamera/ipa_manager.cpp       | 22 +++++++++++++++++++++-
>  src/libcamera/ipa_module.cpp        | 25 -------------------------
>  4 files changed, 23 insertions(+), 28 deletions(-)
> 
> diff --git a/src/libcamera/include/ipa_manager.h b/src/libcamera/include/ipa_manager.h
> index 26edf087461e..0b5fd2ac1f12 100644
> --- a/src/libcamera/include/ipa_manager.h
> +++ b/src/libcamera/include/ipa_manager.h
> @@ -38,6 +38,8 @@ private:
>  		      std::vector<std::string> &files);
>  	unsigned int addDir(const char *libDir, unsigned int maxDepth = 0);
>  
> +	bool isSignatureValid(IPAModule *ipa) const;
> +
>  	static const uint8_t publicKeyData_[];
>  	static const PubKey pubKey_;
>  };
> diff --git a/src/libcamera/include/ipa_module.h b/src/libcamera/include/ipa_module.h
> index ec3671857a61..a9a3511701d4 100644
> --- a/src/libcamera/include/ipa_module.h
> +++ b/src/libcamera/include/ipa_module.h
> @@ -37,8 +37,6 @@ public:
>  	bool match(PipelineHandler *pipe,
>  		   uint32_t minVersion, uint32_t maxVersion) const;
>  
> -	bool isOpenSource() const;
> -
>  private:
>  	struct IPAModuleInfo info_;
>  	std::vector<uint8_t> signature_;
> diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
> index bcaae3564ea1..2b0112885274 100644
> --- a/src/libcamera/ipa_manager.cpp
> +++ b/src/libcamera/ipa_manager.cpp
> @@ -12,6 +12,7 @@
>  #include <string.h>
>  #include <sys/types.h>
>  
> +#include "file.h"
>  #include "ipa_context_wrapper.h"
>  #include "ipa_module.h"
>  #include "ipa_proxy.h"
> @@ -271,7 +272,7 @@ std::unique_ptr<IPAInterface> IPAManager::createIPA(PipelineHandler *pipe,
>  	if (!m)
>  		return nullptr;
>  
> -	if (!m->isOpenSource()) {
> +	if (!isSignatureValid(m)) {
>  		IPAProxyFactory *pf = nullptr;
>  		std::vector<IPAProxyFactory *> &factories = IPAProxyFactory::factories();
>  
> @@ -307,4 +308,23 @@ std::unique_ptr<IPAInterface> IPAManager::createIPA(PipelineHandler *pipe,
>  	return std::make_unique<IPAContextWrapper>(ctx);
>  }
>  
> +bool IPAManager::isSignatureValid(IPAModule *ipa) const
> +{
> +	File file{ ipa->path() };
> +	if (!file.open(File::ReadOnly))
> +		return false;
> +
> +	Span<uint8_t> data = file.map();
> +	if (data.empty())
> +		return false;
> +
> +	bool valid = pubKey_.verify(data, ipa->signature());
> +
> +	LOG(IPAManager, Debug)
> +		<< "IPA module " << ipa->path() << " signature is "
> +		<< (valid ? "valid" : "not valid");
> +
> +	return valid;
> +}
> +
>  } /* namespace libcamera */
> diff --git a/src/libcamera/ipa_module.cpp b/src/libcamera/ipa_module.cpp
> index 51b238a698f2..96b44f13192c 100644
> --- a/src/libcamera/ipa_module.cpp
> +++ b/src/libcamera/ipa_module.cpp
> @@ -472,29 +472,4 @@ bool IPAModule::match(PipelineHandler *pipe,
>  	       !strcmp(info_.pipelineName, pipe->name());
>  }
>  
> -/**
> - * \brief Verify if the IPA module is open source
> - *
> - * \sa IPAModuleInfo::license
> - */
> -bool IPAModule::isOpenSource() const
> -{
> -	static const char *osLicenses[] = {
> -		"GPL-2.0-only",
> -		"GPL-2.0-or-later",
> -		"GPL-3.0-only",
> -		"GPL-3.0-or-later",
> -		"LGPL-2.1-only",
> -		"LGPL-2.1-or-later",
> -		"LGPL-3.0-only",
> -		"LGPL-3.0-or-later",
> -	};
> -
> -	for (unsigned int i = 0; i < ARRAY_SIZE(osLicenses); i++)
> -		if (!strcmp(osLicenses[i], info_.license))
> -			return true;
> -
> -	return false;
> -}
> -
>  } /* namespace libcamera */
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

Patch

diff --git a/src/libcamera/include/ipa_manager.h b/src/libcamera/include/ipa_manager.h
index 26edf087461e..0b5fd2ac1f12 100644
--- a/src/libcamera/include/ipa_manager.h
+++ b/src/libcamera/include/ipa_manager.h
@@ -38,6 +38,8 @@  private:
 		      std::vector<std::string> &files);
 	unsigned int addDir(const char *libDir, unsigned int maxDepth = 0);
 
+	bool isSignatureValid(IPAModule *ipa) const;
+
 	static const uint8_t publicKeyData_[];
 	static const PubKey pubKey_;
 };
diff --git a/src/libcamera/include/ipa_module.h b/src/libcamera/include/ipa_module.h
index ec3671857a61..a9a3511701d4 100644
--- a/src/libcamera/include/ipa_module.h
+++ b/src/libcamera/include/ipa_module.h
@@ -37,8 +37,6 @@  public:
 	bool match(PipelineHandler *pipe,
 		   uint32_t minVersion, uint32_t maxVersion) const;
 
-	bool isOpenSource() const;
-
 private:
 	struct IPAModuleInfo info_;
 	std::vector<uint8_t> signature_;
diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
index bcaae3564ea1..2b0112885274 100644
--- a/src/libcamera/ipa_manager.cpp
+++ b/src/libcamera/ipa_manager.cpp
@@ -12,6 +12,7 @@ 
 #include <string.h>
 #include <sys/types.h>
 
+#include "file.h"
 #include "ipa_context_wrapper.h"
 #include "ipa_module.h"
 #include "ipa_proxy.h"
@@ -271,7 +272,7 @@  std::unique_ptr<IPAInterface> IPAManager::createIPA(PipelineHandler *pipe,
 	if (!m)
 		return nullptr;
 
-	if (!m->isOpenSource()) {
+	if (!isSignatureValid(m)) {
 		IPAProxyFactory *pf = nullptr;
 		std::vector<IPAProxyFactory *> &factories = IPAProxyFactory::factories();
 
@@ -307,4 +308,23 @@  std::unique_ptr<IPAInterface> IPAManager::createIPA(PipelineHandler *pipe,
 	return std::make_unique<IPAContextWrapper>(ctx);
 }
 
+bool IPAManager::isSignatureValid(IPAModule *ipa) const
+{
+	File file{ ipa->path() };
+	if (!file.open(File::ReadOnly))
+		return false;
+
+	Span<uint8_t> data = file.map();
+	if (data.empty())
+		return false;
+
+	bool valid = pubKey_.verify(data, ipa->signature());
+
+	LOG(IPAManager, Debug)
+		<< "IPA module " << ipa->path() << " signature is "
+		<< (valid ? "valid" : "not valid");
+
+	return valid;
+}
+
 } /* namespace libcamera */
diff --git a/src/libcamera/ipa_module.cpp b/src/libcamera/ipa_module.cpp
index 51b238a698f2..96b44f13192c 100644
--- a/src/libcamera/ipa_module.cpp
+++ b/src/libcamera/ipa_module.cpp
@@ -472,29 +472,4 @@  bool IPAModule::match(PipelineHandler *pipe,
 	       !strcmp(info_.pipelineName, pipe->name());
 }
 
-/**
- * \brief Verify if the IPA module is open source
- *
- * \sa IPAModuleInfo::license
- */
-bool IPAModule::isOpenSource() const
-{
-	static const char *osLicenses[] = {
-		"GPL-2.0-only",
-		"GPL-2.0-or-later",
-		"GPL-3.0-only",
-		"GPL-3.0-or-later",
-		"LGPL-2.1-only",
-		"LGPL-2.1-or-later",
-		"LGPL-3.0-only",
-		"LGPL-3.0-or-later",
-	};
-
-	for (unsigned int i = 0; i < ARRAY_SIZE(osLicenses); i++)
-		if (!strcmp(osLicenses[i], info_.license))
-			return true;
-
-	return false;
-}
-
 } /* namespace libcamera */