summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/efi_api.h12
-rw-r--r--include/efi_loader.h3
-rw-r--r--lib/efi_loader/efi_image_loader.c8
-rw-r--r--lib/efi_loader/efi_signature.c49
4 files changed, 60 insertions, 12 deletions
diff --git a/include/efi_api.h b/include/efi_api.h
index f123d0557c6..982c2001728 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -1849,9 +1849,21 @@ struct efi_system_resource_table {
#define LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL_VENDOR_RANGE_MAX 0x00004000
/* Certificate types in signature database */
+#define EFI_CERT_SHA1_GUID \
+ EFI_GUID(0x826ca512, 0xcf10, 0x4ac9, 0xb1, 0x87, \
+ 0xbe, 0x01, 0x49, 0x66, 0x31, 0xbd)
+#define EFI_CERT_SHA224_GUID \
+ EFI_GUID(0xb6e5233, 0xa65c, 0x44c9, 0x94, 0x07, \
+ 0xd9, 0xab, 0x83, 0xbf, 0xc8, 0xbd)
#define EFI_CERT_SHA256_GUID \
EFI_GUID(0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, \
0x41, 0xf9, 0x36, 0x93, 0x43, 0x28)
+#define EFI_CERT_SHA384_GUID \
+ EFI_GUID(0xff3e5307, 0x9fd0, 0x48c9, 0x85, 0xf1, \
+ 0x8a, 0xd5, 0x6c, 0x70, 0x1e, 0x01)
+#define EFI_CERT_SHA512_GUID \
+ EFI_GUID(0x93e0fae, 0xa6c4, 0x4f50, 0x9f, 0x1b, \
+ 0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a)
#define EFI_CERT_RSA2048_GUID \
EFI_GUID(0x3c5766e8, 0x269c, 0x4e34, 0xaa, 0x14, \
0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6)
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 1fa75b40fea..4e50f2d0c36 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -912,7 +912,8 @@ struct x509_certificate;
struct pkcs7_message;
bool efi_signature_lookup_digest(struct efi_image_regions *regs,
- struct efi_signature_store *db);
+ struct efi_signature_store *db,
+ bool dbx);
bool efi_signature_verify(struct efi_image_regions *regs,
struct pkcs7_message *msg,
struct efi_signature_store *db,
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index 255613eb72b..f43dfb3d57e 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -545,13 +545,13 @@ static bool efi_image_unsigned_authenticate(struct efi_image_regions *regs)
}
/* try black-list first */
- if (efi_signature_lookup_digest(regs, dbx)) {
+ if (efi_signature_lookup_digest(regs, dbx, true)) {
EFI_PRINT("Image is not signed and its digest found in \"dbx\"\n");
goto out;
}
/* try white-list */
- if (efi_signature_lookup_digest(regs, db))
+ if (efi_signature_lookup_digest(regs, db, false))
ret = true;
else
EFI_PRINT("Image is not signed and its digest not found in \"db\" or \"dbx\"\n");
@@ -633,7 +633,7 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
goto err;
}
- if (efi_signature_lookup_digest(regs, dbx)) {
+ if (efi_signature_lookup_digest(regs, dbx, true)) {
EFI_PRINT("Image's digest was found in \"dbx\"\n");
goto err;
}
@@ -734,7 +734,7 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
EFI_PRINT("Signature was not verified by \"db\"\n");
- if (efi_signature_lookup_digest(regs, db)) {
+ if (efi_signature_lookup_digest(regs, db, false)) {
ret = true;
break;
}
diff --git a/lib/efi_loader/efi_signature.c b/lib/efi_loader/efi_signature.c
index 3243e2c60de..eb6886cdccd 100644
--- a/lib/efi_loader/efi_signature.c
+++ b/lib/efi_loader/efi_signature.c
@@ -147,9 +147,34 @@ static bool efi_hash_regions(struct image_region *regs, int count,
}
/**
+ * hash_algo_supported - check if the requested hash algorithm is supported
+ * @guid: guid of the algorithm
+ *
+ * Return: true if supported false otherwise
+ */
+static bool hash_algo_supported(const efi_guid_t guid)
+{
+ int i;
+ const efi_guid_t unsupported_hashes[] = {
+ EFI_CERT_SHA1_GUID,
+ EFI_CERT_SHA224_GUID,
+ EFI_CERT_SHA384_GUID,
+ EFI_CERT_SHA512_GUID,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(unsupported_hashes); i++) {
+ if (!guidcmp(&unsupported_hashes[i], &guid))
+ return false;
+ }
+
+ return true;
+}
+
+/**
* efi_signature_lookup_digest - search for an image's digest in sigdb
* @regs: List of regions to be authenticated
* @db: Signature database for trusted certificates
+ * @dbx Caller needs to set this to true if he is searching dbx
*
* A message digest of image pointed to by @regs is calculated and
* its hash value is compared to entries in signature database pointed
@@ -158,7 +183,9 @@ static bool efi_hash_regions(struct image_region *regs, int count,
* Return: true if found, false if not
*/
bool efi_signature_lookup_digest(struct efi_image_regions *regs,
- struct efi_signature_store *db)
+ struct efi_signature_store *db,
+ bool dbx)
+
{
struct efi_signature_store *siglist;
struct efi_sig_data *sig_data;
@@ -172,12 +199,20 @@ bool efi_signature_lookup_digest(struct efi_image_regions *regs,
goto out;
for (siglist = db; siglist; siglist = siglist->next) {
- /* TODO: support other hash algorithms */
- if (guidcmp(&siglist->sig_type, &efi_guid_sha256)) {
- EFI_PRINT("Digest algorithm is not supported: %pUs\n",
- &siglist->sig_type);
- break;
- }
+ /*
+ * if the hash algorithm is unsupported and we get an entry in
+ * dbx reject the image
+ */
+ if (dbx && !hash_algo_supported(siglist->sig_type)) {
+ found = true;
+ continue;
+ };
+ /*
+ * Only support sha256 for now, that's what
+ * hash-to-efi-sig-list produces
+ */
+ if (guidcmp(&siglist->sig_type, &efi_guid_sha256))
+ continue;
if (!efi_hash_regions(regs->reg, regs->num, &hash, &size)) {
EFI_PRINT("Digesting an image failed\n");