]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
kexec_file: use SHA-256 library API instead of crypto_shash API
authorEric Biggers <ebiggers@google.com>
Mon, 28 Apr 2025 18:57:20 +0000 (11:57 -0700)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 12 May 2025 00:54:12 +0000 (17:54 -0700)
This user of SHA-256 does not support any other algorithm, so the
crypto_shash abstraction provides no value.  Just use the SHA-256 library
API instead, which is much simpler and easier to use.

Tested with '/sbin/kexec --kexec-file-syscall'.

Link: https://lkml.kernel.org/r/20250428185721.844686-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: Dave Young <dyoung@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
kernel/Kconfig.kexec
kernel/kexec_file.c

index 4d111f871951676544ed248b394c22b157b9536a..9fea9dca15bd236416dc461e4539fcab86dc81d3 100644 (file)
@@ -38,8 +38,7 @@ config KEXEC
 config KEXEC_FILE
        bool "Enable kexec file based system call"
        depends on ARCH_SUPPORTS_KEXEC_FILE
-       select CRYPTO
-       select CRYPTO_SHA256
+       select CRYPTO_LIB_SHA256
        select KEXEC_CORE
        help
          This is new version of kexec system call. This system call is
index fba686487e3b511675da0206c65ed2c0a9c65aff..14e5087b4277131af7befeef02f2ebd918e395fc 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/list.h>
 #include <linux/fs.h>
 #include <linux/ima.h>
-#include <crypto/hash.h>
 #include <crypto/sha2.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
@@ -712,11 +711,10 @@ int kexec_add_buffer(struct kexec_buf *kbuf)
 /* Calculate and store the digest of segments */
 static int kexec_calculate_store_digests(struct kimage *image)
 {
-       struct crypto_shash *tfm;
-       struct shash_desc *desc;
+       struct sha256_state state;
        int ret = 0, i, j, zero_buf_sz, sha_region_sz;
-       size_t desc_size, nullsz;
-       char *digest;
+       size_t nullsz;
+       u8 digest[SHA256_DIGEST_SIZE];
        void *zero_buf;
        struct kexec_sha_region *sha_regions;
        struct purgatory_info *pi = &image->purgatory_info;
@@ -727,37 +725,12 @@ static int kexec_calculate_store_digests(struct kimage *image)
        zero_buf = __va(page_to_pfn(ZERO_PAGE(0)) << PAGE_SHIFT);
        zero_buf_sz = PAGE_SIZE;
 
-       tfm = crypto_alloc_shash("sha256", 0, 0);
-       if (IS_ERR(tfm)) {
-               ret = PTR_ERR(tfm);
-               goto out;
-       }
-
-       desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
-       desc = kzalloc(desc_size, GFP_KERNEL);
-       if (!desc) {
-               ret = -ENOMEM;
-               goto out_free_tfm;
-       }
-
        sha_region_sz = KEXEC_SEGMENT_MAX * sizeof(struct kexec_sha_region);
        sha_regions = vzalloc(sha_region_sz);
-       if (!sha_regions) {
-               ret = -ENOMEM;
-               goto out_free_desc;
-       }
-
-       desc->tfm   = tfm;
-
-       ret = crypto_shash_init(desc);
-       if (ret < 0)
-               goto out_free_sha_regions;
+       if (!sha_regions)
+               return -ENOMEM;
 
-       digest = kzalloc(SHA256_DIGEST_SIZE, GFP_KERNEL);
-       if (!digest) {
-               ret = -ENOMEM;
-               goto out_free_sha_regions;
-       }
+       sha256_init(&state);
 
        for (j = i = 0; i < image->nr_segments; i++) {
                struct kexec_segment *ksegment;
@@ -776,10 +749,7 @@ static int kexec_calculate_store_digests(struct kimage *image)
                if (ksegment->kbuf == pi->purgatory_buf)
                        continue;
 
-               ret = crypto_shash_update(desc, ksegment->kbuf,
-                                         ksegment->bufsz);
-               if (ret)
-                       break;
+               sha256_update(&state, ksegment->kbuf, ksegment->bufsz);
 
                /*
                 * Assume rest of the buffer is filled with zero and
@@ -791,44 +761,26 @@ static int kexec_calculate_store_digests(struct kimage *image)
 
                        if (bytes > zero_buf_sz)
                                bytes = zero_buf_sz;
-                       ret = crypto_shash_update(desc, zero_buf, bytes);
-                       if (ret)
-                               break;
+                       sha256_update(&state, zero_buf, bytes);
                        nullsz -= bytes;
                }
 
-               if (ret)
-                       break;
-
                sha_regions[j].start = ksegment->mem;
                sha_regions[j].len = ksegment->memsz;
                j++;
        }
 
-       if (!ret) {
-               ret = crypto_shash_final(desc, digest);
-               if (ret)
-                       goto out_free_digest;
-               ret = kexec_purgatory_get_set_symbol(image, "purgatory_sha_regions",
-                                                    sha_regions, sha_region_sz, 0);
-               if (ret)
-                       goto out_free_digest;
+       sha256_final(&state, digest);
 
-               ret = kexec_purgatory_get_set_symbol(image, "purgatory_sha256_digest",
-                                                    digest, SHA256_DIGEST_SIZE, 0);
-               if (ret)
-                       goto out_free_digest;
-       }
+       ret = kexec_purgatory_get_set_symbol(image, "purgatory_sha_regions",
+                                            sha_regions, sha_region_sz, 0);
+       if (ret)
+               goto out_free_sha_regions;
 
-out_free_digest:
-       kfree(digest);
+       ret = kexec_purgatory_get_set_symbol(image, "purgatory_sha256_digest",
+                                            digest, SHA256_DIGEST_SIZE, 0);
 out_free_sha_regions:
        vfree(sha_regions);
-out_free_desc:
-       kfree(desc);
-out_free_tfm:
-       kfree(tfm);
-out:
        return ret;
 }