[libcamera-devel] [PATCH v2 3/4] libcamera: pub_key: Support openssl as an alternative to gnutls

Eric Curtin ecurtin at redhat.com
Tue Aug 9 14:37:51 CEST 2022


On Tue, 9 Aug 2022 at 13:24, Kieran Bingham
<kieran.bingham at ideasonboard.com> wrote:
>
> Quoting Eric Curtin via libcamera-devel (2022-08-09 11:46:09)
> > On Tue, 9 Aug 2022 at 00:18, Laurent Pinchart via libcamera-devel
> > <libcamera-devel at lists.libcamera.org> wrote:
> > >
> > > On Tue, Aug 09, 2022 at 02:08:32AM +0300, Laurent Pinchart via libcamera-devel wrote:
> > > > Support verify IPA signatures with openssl as an alternative to gnutls,
> > > > to offer more flexibility in the selection of dependencies. Use gnutls
> > > > by default, for no specific reason as both are equally well supported.
> > > >
> > > > Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > > > ---
> > > > Changes since v1:
> > > >
> > > > - Don't use functions deprecated in OpenSSL 3.0
> > > > ---
> > > >  README.rst                           |  2 +-
> > > >  include/libcamera/internal/pub_key.h |  8 +++--
> > > >  src/libcamera/meson.build            | 10 ++++--
> > > >  src/libcamera/pub_key.cpp            | 47 +++++++++++++++++++++++++---
> > > >  4 files changed, 57 insertions(+), 10 deletions(-)
> > > >
> > > > diff --git a/README.rst b/README.rst
> > > > index 77374c6a72b1..3bf4685b0e15 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 a22ba037cff6..8653a912b2d5 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 7cc06de4aedc..401fc498cfbc 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('gnutls2', required : false)
> > >
> > > This should have been
> > >
> > > libcrypto = dependency('gnutls', required : false)
>
> I'm a bit bemused by this, as gnutls != libcrypto?

I was briefly bemused as when I saw libcrypto here, I normally
automatically assume the openssl one because that's what it's called.
But they are both cryptographic libraries so I get the context here.

>
> But I see it's just to be able to reference a single dep variable.
>
>
> > >
> >
> > With this change:
> >
> > Reviewed-by: Eric Curtin <ecurtin at redhat.com>
> >
> > > It was a test left-over, sorry.
> > >
> > > > +if libcrypto.found()
> > > >      config_h.set('HAVE_GNUTLS', 1)
> > > > +else
> > > > +    libcrypto = dependency('libcrypto', required : true)
> > > > +    config_h.set('HAVE_CRYPTO', 1)
>
> and at this point, libcrypto is either of gnutls, or libcrypto.
>
> I don't have anything much better to offer as an alternative so lets
> carry on.
>
>
> Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
>
> > > >  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 b2045a103bc0..64dfa23497c2 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())
> > >
> > > --
> > > Regards,
> > >
> > > Laurent Pinchart
> > >
> >
>



More information about the libcamera-devel mailing list