summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.rst2
-rw-r--r--include/libcamera/internal/pub_key.h8
-rw-r--r--src/libcamera/meson.build10
-rw-r--r--src/libcamera/pub_key.cpp47
4 files changed, 57 insertions, 10 deletions
diff --git a/README.rst b/README.rst
index 77374c6a..3bf4685b 100644
--- a/README.rst
+++ b/README.rst
@@ -61,7 +61,7 @@ for the libcamera core: [required]
libyaml-dev python3-yaml python3-ply python3-jinja2
for IPA module signing: [required]
- libgnutls28-dev openssl
+ Either libgnutls28-dev or libssl-dev, openssl
for improved debugging: [optional]
libdw-dev libunwind-dev
diff --git a/include/libcamera/internal/pub_key.h b/include/libcamera/internal/pub_key.h
index a22ba037..8653a912 100644
--- a/include/libcamera/internal/pub_key.h
+++ b/include/libcamera/internal/pub_key.h
@@ -11,7 +11,9 @@
#include <libcamera/base/span.h>
-#if HAVE_GNUTLS
+#if HAVE_CRYPTO
+struct evp_pkey_st;
+#elif HAVE_GNUTLS
struct gnutls_pubkey_st;
#endif
@@ -28,7 +30,9 @@ public:
private:
bool valid_;
-#if HAVE_GNUTLS
+#if HAVE_CRYPTO
+ struct evp_pkey_st *pubkey_;
+#elif HAVE_GNUTLS
struct gnutls_pubkey_st *pubkey_;
#endif
};
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 7cc06de4..1f02494a 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -65,12 +65,16 @@ subdir('pipeline')
subdir('proxy')
libdl = cc.find_library('dl')
-libgnutls = dependency('gnutls', required : true)
libudev = dependency('libudev', required : false)
libyaml = dependency('yaml-0.1', required : false)
-if libgnutls.found()
+# Use one of gnutls or libcrypto (provided by OpenSSL), trying gnutls first.
+libcrypto = dependency('gnutls', required : false)
+if libcrypto.found()
config_h.set('HAVE_GNUTLS', 1)
+else
+ libcrypto = dependency('libcrypto', required : true)
+ config_h.set('HAVE_CRYPTO', 1)
endif
if liblttng.found()
@@ -135,8 +139,8 @@ libcamera_deps = [
libatomic,
libcamera_base,
libcamera_base_private,
+ libcrypto,
libdl,
- libgnutls,
liblttng,
libudev,
libyaml,
diff --git a/src/libcamera/pub_key.cpp b/src/libcamera/pub_key.cpp
index b2045a10..64dfa234 100644
--- a/src/libcamera/pub_key.cpp
+++ b/src/libcamera/pub_key.cpp
@@ -7,7 +7,12 @@
#include "libcamera/internal/pub_key.h"
-#if HAVE_GNUTLS
+#if HAVE_CRYPTO
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <openssl/sha.h>
+#include <openssl/x509.h>
+#elif HAVE_GNUTLS
#include <gnutls/abstract.h>
#endif
@@ -33,7 +38,14 @@ namespace libcamera {
PubKey::PubKey([[maybe_unused]] Span<const uint8_t> key)
: valid_(false)
{
-#if HAVE_GNUTLS
+#if HAVE_CRYPTO
+ const uint8_t *data = key.data();
+ pubkey_ = d2i_PUBKEY(nullptr, &data, key.size());
+ if (!pubkey_)
+ return;
+
+ valid_ = true;
+#elif HAVE_GNUTLS
int ret = gnutls_pubkey_init(&pubkey_);
if (ret < 0)
return;
@@ -52,7 +64,9 @@ PubKey::PubKey([[maybe_unused]] Span<const uint8_t> key)
PubKey::~PubKey()
{
-#if HAVE_GNUTLS
+#if HAVE_CRYPTO
+ EVP_PKEY_free(pubkey_);
+#elif HAVE_GNUTLS
gnutls_pubkey_deinit(pubkey_);
#endif
}
@@ -79,7 +93,32 @@ bool PubKey::verify([[maybe_unused]] Span<const uint8_t> data,
if (!valid_)
return false;
-#if HAVE_GNUTLS
+#if HAVE_CRYPTO
+ /*
+ * Create and initialize a public key algorithm context for signature
+ * verification.
+ */
+ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pubkey_, nullptr);
+ if (!ctx)
+ return false;
+
+ if (EVP_PKEY_verify_init(ctx) <= 0 ||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0 ||
+ EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ return false;
+ }
+
+ /* Calculate the SHA256 digest of the data. */
+ uint8_t digest[SHA256_DIGEST_LENGTH];
+ SHA256(data.data(), data.size(), digest);
+
+ /* Decrypt the signature and verify it matches the digest. */
+ int ret = EVP_PKEY_verify(ctx, sig.data(), sig.size(), digest,
+ SHA256_DIGEST_LENGTH);
+ EVP_PKEY_CTX_free(ctx);
+ return ret == 1;
+#elif HAVE_GNUTLS
const gnutls_datum_t gnuTlsData{
const_cast<unsigned char *>(data.data()),
static_cast<unsigned int>(data.size())