1 | // SPDX-License-Identifier: GPL-2.0-only |
---|---|
2 | /* |
3 | * purgatory: Runs between two kernels |
4 | * |
5 | * Copyright (C) 2014 Red Hat Inc. |
6 | * |
7 | * Author: |
8 | * Vivek Goyal <vgoyal@redhat.com> |
9 | */ |
10 | |
11 | #include <linux/bug.h> |
12 | #include <linux/kernel.h> |
13 | #include <linux/types.h> |
14 | #include <crypto/sha2.h> |
15 | #include <asm/purgatory.h> |
16 | |
17 | #include "../boot/compressed/error.h" |
18 | #include "../boot/string.h" |
19 | |
20 | u8 purgatory_sha256_digest[SHA256_DIGEST_SIZE] __section(".kexec-purgatory"); |
21 | |
22 | struct kexec_sha_region purgatory_sha_regions[KEXEC_SEGMENT_MAX] __section(".kexec-purgatory"); |
23 | |
24 | static int verify_sha256_digest(void) |
25 | { |
26 | struct kexec_sha_region *ptr, *end; |
27 | u8 digest[SHA256_DIGEST_SIZE]; |
28 | struct sha256_state sctx; |
29 | |
30 | sha256_init(sctx: &sctx); |
31 | end = purgatory_sha_regions + ARRAY_SIZE(purgatory_sha_regions); |
32 | |
33 | for (ptr = purgatory_sha_regions; ptr < end; ptr++) |
34 | sha256_update(sctx: &sctx, data: (uint8_t *)(ptr->start), len: ptr->len); |
35 | |
36 | sha256_final(sctx: &sctx, out: digest); |
37 | |
38 | if (memcmp(digest, purgatory_sha256_digest, sizeof(digest))) |
39 | return 1; |
40 | |
41 | return 0; |
42 | } |
43 | |
44 | void purgatory(void) |
45 | { |
46 | int ret; |
47 | |
48 | ret = verify_sha256_digest(); |
49 | if (ret) { |
50 | /* loop forever */ |
51 | for (;;) |
52 | ; |
53 | } |
54 | } |
55 | |
56 | /* |
57 | * Defined in order to reuse memcpy() and memset() from |
58 | * arch/x86/boot/compressed/string.c |
59 | */ |
60 | void warn(const char *msg) {} |
61 |