diff --git a/meson_options.txt b/meson_options.txt
index 20baacc4..18488e6b 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -46,6 +46,14 @@ option('gstreamer',
         value : 'auto',
         description : 'Compile libcamera GStreamer plugin')
 
+option('ipa-signature-algo',
+        type : 'combo',
+        choices : [
+            'rsa-sha256',
+            'ml-dsa-65',
+        ],
+        description : 'Select a signature algorithm to sign IPA libraries.')
+
 option('ipas',
         type : 'array',
         choices : ['ipu3', 'mali-c55', 'rkisp1', 'rpi/pisp', 'rpi/vc4', 'simple',
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 575408b2..cabd1041 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -89,14 +89,25 @@ libyaml = dependency('yaml-0.1', default_options : [
 # Use one of gnutls or libcrypto (provided by OpenSSL), trying gnutls first.
 libcrypto = dependency('gnutls', required : false)
 if libcrypto.found()
+    r = run_command('../../utils/check-algo.sh', 'guntls', get_option('ipa-signature-algo'), check: false)
+    if r.returncode() != 0
+        error('Unsupported signature algorithm (', 'guntls,', get_option('ipa-signature-algo'), ')')
+    endif
     config_h.set('HAVE_GNUTLS', 1)
 else
     libcrypto = dependency('libcrypto', required : false)
     if libcrypto.found()
+            r = run_command('../../utils/check-algo.sh', 'openssl',  get_option('ipa-signature-algo'), check: false)
+            if r.returncode() != 0
+                error('Unsupported signature algorithm. (', 'libcrypto,', get_option('ipa-signature-algo'), ')')
+            endif
         config_h.set('HAVE_CRYPTO', 1)
     endif
 endif
 
+# comply with FIPS 204
+config_h.set('IPA_MODULE_DIR_SIGNATURE_ALGO', '"' + get_option('ipa-signature-algo') + '"')
+
 if not libcrypto.found()
     warning('Neither gnutls nor libcrypto found, all IPA modules will be isolated')
     summary({'IPA modules signed with': 'None (modules will run isolated)'},
diff --git a/src/meson.build b/src/meson.build
index 9b63c8e8..4111f591 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -19,7 +19,11 @@ openssl = find_program('openssl', required : false)
 if openssl.found()
     ipa_priv_key = custom_target('ipa-priv-key',
                                  output : ['ipa-priv-key.pem'],
-                                 command : [gen_ipa_priv_key, '@OUTPUT@'])
+                                 command : [
+                                    gen_ipa_priv_key,
+                                    get_option('ipa-signature-algo'),
+                                    '@OUTPUT@'
+                                 ])
     config_h.set('HAVE_IPA_PUBKEY', 1)
     ipa_sign_module = true
 else
diff --git a/utils/check-algo.sh b/utils/check-algo.sh
new file mode 100755
index 00000000..2ee6c7cb
--- /dev/null
+++ b/utils/check-algo.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2026, Red Hat Inc.
+#
+# Author: Kate Hsuan <hpa@redhat.com>
+#
+# Check if the given algorithm is supported by the library
+
+tool="$1"
+algo="$2"
+
+if [ "$algo" = "rsa-sha256" ]; then
+    algo="RSA-SHA256"
+elif [ "$algo" = "ml-dsa-65" ]; then
+    algo="ML-DSA-65"
+else
+    echo "Invalid algorithm: $algo"
+    exit 1
+fi
+
+if [ "$tool" = "guntls" ]; then
+    gnutls-cli -l | grep "$algo" > /dev/null
+    ret=$?
+elif [ "$tool" = "openssl" ]; then
+    openssl list -signature-algorithms |grep ${algo} > /dev/null
+    ret=$?
+else
+    echo "Invalid tool: $tool"
+    exit 1
+fi
+
+if [ $ret -ne 0 ]; then
+    echo "Algorithm $algo is not supported by $tool"
+    exit 1
+fi
diff --git a/utils/gen-ipa-priv-key.sh b/utils/gen-ipa-priv-key.sh
index 2ca7b883..3fc44bcc 100755
--- a/utils/gen-ipa-priv-key.sh
+++ b/utils/gen-ipa-priv-key.sh
@@ -4,8 +4,23 @@
 #
 # Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 #
-# Generate an RSA private key to sign IPA modules
+# Generate an private key for the given algorithm to sign IPA modules
 
-key="$1"
+algo="$1"
+key="$2"
 
-openssl genpkey -algorithm RSA -out "${key}" -pkeyopt rsa_keygen_bits:2048
+if [ -e "${key}" ]; then
+    echo "File ${key} already exists. Removing it."
+    rm "${key}"
+fi
+
+# Two possible algorithms: RSA and ML-DSA-65
+
+if [ "$algo" = "rsa-sha256" ]; then
+    openssl genpkey -algorithm RSA -out "${key}"
+elif [ "$algo" = "ml-dsa-65" ]; then
+    openssl genpkey -algorithm ML-DSA-65 -out "${key}"
+else
+    echo "Invalid algorithm: $algo"
+    exit 1
+fi
