From 52579639ce1b17de251fc69619d95d18b93fb377 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 5 May 2023 18:03:00 +0300 Subject: apps: Add ipa-verify application When packaging libcamera, distributions may break IPA module signatures if the packaging process strips binaries. This can be fixed by resigning the modules, but the process is error-prone. Add a command line ipa-verify utility that tests the signature on an IPA module to help packagers. The tool takes a single argument, the path to an IPA module shared object, and expects the signature file (.sign) to be in the same directory. In order to access the public key needed for signature verification, add a static function to the IPAManager class. As the class is internal to libcamera, this doesn't affect the public API. Signed-off-by: Laurent Pinchart Reviewed-by: Umang Jain Reviewed-by: Kieran Bingham Tested-by: Javier Martinez Canillas --- src/apps/ipa-verify/main.cpp | 64 +++++++++++++++++++++++++++++++++++++++++ src/apps/ipa-verify/meson.build | 15 ++++++++++ src/apps/meson.build | 2 ++ 3 files changed, 81 insertions(+) create mode 100644 src/apps/ipa-verify/main.cpp create mode 100644 src/apps/ipa-verify/meson.build (limited to 'src/apps') diff --git a/src/apps/ipa-verify/main.cpp b/src/apps/ipa-verify/main.cpp new file mode 100644 index 00000000..76ba5073 --- /dev/null +++ b/src/apps/ipa-verify/main.cpp @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2023, Ideas on Board Oy + * + * ipa_verify.cpp - Verify signature on an IPA module + */ + +#include +#include + +#include +#include + +#include "libcamera/internal/ipa_manager.h" +#include "libcamera/internal/ipa_module.h" + +using namespace libcamera; + +namespace { + +bool isSignatureValid(IPAModule *ipa) +{ + File file{ ipa->path() }; + if (!file.open(File::OpenModeFlag::ReadOnly)) + return false; + + Span data = file.map(); + if (data.empty()) + return false; + + return IPAManager::pubKey().verify(data, ipa->signature()); +} + +void usage(char *argv0) +{ + std::cout << "Usage: " << basename(argv0) << " ipa_name.so" << std::endl; + std::cout << std::endl; + std::cout << "Verify the signature of an IPA module. The signature file ipa_name.so.sign is" << std::endl; + std::cout << "expected to be in the same directory as the IPA module." << std::endl; +} + +} /* namespace */ + +int main(int argc, char **argv) +{ + if (argc != 2) { + usage(argv[0]); + return EXIT_FAILURE; + } + + IPAModule module{ argv[1] }; + if (!module.isValid()) { + std::cout << "Invalid IPA module " << argv[1] << std::endl; + return EXIT_FAILURE; + } + + if (!isSignatureValid(&module)) { + std::cout << "IPA module signature is invalid" << std::endl; + return EXIT_FAILURE; + } + + std::cout << "IPA module signature is valid" << std::endl; + return 0; +} diff --git a/src/apps/ipa-verify/meson.build b/src/apps/ipa-verify/meson.build new file mode 100644 index 00000000..7fdda3b9 --- /dev/null +++ b/src/apps/ipa-verify/meson.build @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: CC0-1.0 + +if not ipa_sign_module + subdir_done() +endif + +ipa_verify_sources = files([ + 'main.cpp', +]) + +ipa_verify = executable('ipa_verify', ipa_verify_sources, + dependencies : [ + libcamera_private, + ], + install : false) diff --git a/src/apps/meson.build b/src/apps/meson.build index 09987635..af632b9a 100644 --- a/src/apps/meson.build +++ b/src/apps/meson.build @@ -18,3 +18,5 @@ subdir('lc-compliance') subdir('cam') subdir('qcam') + +subdir('ipa-verify') -- cgit v1.2.1