tpm2-setup: Don't fail if we can't access the TPM due to authorization failure
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 17 May 2024 14:20:11 +0000 (16:20 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 18 Jun 2024 18:41:01 +0000 (20:41 +0200)
The TPM might be password/pin protected for various reasons even if
there is no SRK yet. Let's handle those cases gracefully instead of
failing the unit as it is enabled by default.

(cherry picked from commit d6518003f8ebbfb6f85dbf227736ae05b0961199)

catalog/systemd.catalog.in
src/shared/tpm2-util.c
src/systemd/sd-messages.h
src/tpm2-setup/tpm2-setup.c
units/systemd-tpm2-setup-early.service.in
units/systemd-tpm2-setup.service.in

index 3c9a6860dab88712bc0eb47322b1d34259b33e20..2831152763ece1623c499ed938e924f52f6a7152 100644 (file)
@@ -780,3 +780,16 @@ Documentation: https://systemd.io/PORTABLE_SERVICES/
 A Portable Service @PORTABLE_ROOT@ (with extensions: @PORTABLE_EXTENSION@) has been
 detached from the system and is no longer available for use. The list of attached
 Portable Services can be queried with 'portablectl list'.
+
+-- ad7089f928ac4f7ea00c07457d47ba8a
+Subject: Authorization failure while attempting to enroll SRK into TPM
+Defined-By: systemd
+Support: %SUPPORT_URL%
+Documentation: man:systemd-tpm2-setup.service(8)
+
+An authorization failure occured while attempting to enroll a Storage Root Key (SRK) on the Trusted Platform
+Module (TPM). Most likely this means that a PIN/Password (authValue) has been set on the Owner hierarchy of
+the TPM.
+
+Automatic SRK enrollment on TPMs in such scenarios is not supported. In order to unset the PIN/password
+protection on the owner hierarchy issue a command like the following: 'tpm2_changeauth -c o -p <OLDPW> ""'.
index 87ce53cf954c6fbb9e673d516a0ee77aa9e30e42..9603f1837eddca20058d987582599ff1a4a57029 100644 (file)
@@ -2119,6 +2119,8 @@ int tpm2_create_primary(
                         /* creationData= */ NULL,
                         /* creationHash= */ NULL,
                         /* creationTicket= */ NULL);
+        if (rc == TPM2_RC_BAD_AUTH)
+                return log_debug_errno(SYNTHETIC_ERRNO(EDEADLK), "Authorization failure while attempting to enroll SRK into TPM.");
         if (rc != TSS2_RC_SUCCESS)
                 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
                                        "Failed to generate primary key in TPM: %s",
index e3f68068a8437caedd4cdee78bdffedd4ade479f..16e9986be36a10df9f3fa8880899679f88c1a42d 100644 (file)
@@ -272,6 +272,9 @@ _SD_BEGIN_DECLARATIONS;
 #define SD_MESSAGE_PORTABLE_DETACHED                  SD_ID128_MAKE(76,c5,c7,54,d6,28,49,0d,8e,cb,a4,c9,d0,42,11,2b)
 #define SD_MESSAGE_PORTABLE_DETACHED_STR              SD_ID128_MAKE_STR(76,c5,c7,54,d6,28,49,0d,8e,cb,a4,c9,d0,42,11,2b)
 
+#define SD_MESSAGE_SRK_ENROLLMENT_NEEDS_AUTHORIZATION     SD_ID128_MAKE(ad,70,89,f9,28,ac,4f,7e,a0,0c,07,45,7d,47,ba,8a)
+#define SD_MESSAGE_SRK_ENROLLMENT_NEEDS_AUTHORIZATION_STR SD_ID128_MAKE_STR(ad,70,89,f9,28,ac,4f,7e,a0,0c,07,45,7d,47,ba,8a)
+
 _SD_END_DECLARATIONS;
 
 #endif
index 35628fc02a88bfaf2783f194f74b89ec90dff92a..b95c5e7a581b99ad5fe2aa585bd26d1602cacd71 100644 (file)
@@ -3,6 +3,8 @@
 #include <getopt.h>
 #include <unistd.h>
 
+#include "sd-messages.h"
+
 #include "build.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -223,6 +225,8 @@ static int load_public_key_tpm2(struct public_key_data *ret) {
                         /* ret_name= */ NULL,
                         /* ret_qname= */ NULL,
                         NULL);
+        if (r == -EDEADLK)
+                return r;
         if (r < 0)
                 return log_error_errno(r, "Failed to get or create SRK: %m");
         if (r > 0)
@@ -289,6 +293,13 @@ static int run(int argc, char *argv[]) {
         }
 
         r = load_public_key_tpm2(&tpm2_key);
+        if (r == -EDEADLK) {
+                log_struct_errno(LOG_INFO, r,
+                                 LOG_MESSAGE("Insufficient permissions to access TPM, not generating SRK."),
+                                 "MESSAGE_ID=" SD_MESSAGE_SRK_ENROLLMENT_NEEDS_AUTHORIZATION_STR);
+                return 76; /* Special return value which means "Insufficient permissions to access TPM,
+                            * cannot generate SRK". This isn't really an error when called at boot. */;
+        }
         if (r < 0)
                 return r;
 
@@ -383,4 +394,4 @@ static int run(int argc, char *argv[]) {
         return 0;
 }
 
-DEFINE_MAIN_FUNCTION(run);
+DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
index 9982c84aba086284be30b82f2d5adb48022b212a..7fdb99b53f36a085059f3bc1873f55b1e0fd80b0 100644 (file)
@@ -21,3 +21,6 @@ ConditionPathExists=!/run/systemd/tpm2-srk-public-key.pem
 Type=oneshot
 RemainAfterExit=yes
 ExecStart={{LIBEXECDIR}}/systemd-tpm2-setup --early=yes --graceful
+
+# The tool returns 76 if the TPM cannot be accessed due to an authorization failure and we can't generate an SRK.
+SuccessExitStatus=76
index 0af72925288a5481a655be8e90ec4fe3e6ddf62e..ac29a769660d39aade5f7272034a4c729bd0f7e1 100644 (file)
@@ -22,3 +22,6 @@ ConditionPathExists=!/etc/initrd-release
 Type=oneshot
 RemainAfterExit=yes
 ExecStart={{LIBEXECDIR}}/systemd-tpm2-setup --graceful
+
+# The tool returns 76 if the TPM cannot be accessed due to an authorization failure and we can't generate an SRK.
+SuccessExitStatus=76