1 | // SPDX-License-Identifier: GPL-2.0-only |
---|---|
2 | /* |
3 | * purgatory: Runs between two kernels |
4 | * |
5 | * Copyright (C) 2022 Huawei Technologies Co, Ltd. |
6 | * |
7 | * Author: Li Zhengyu (lizhengyu3@huawei.com) |
8 | * |
9 | */ |
10 | |
11 | #include <linux/purgatory.h> |
12 | #include <linux/kernel.h> |
13 | #include <linux/string.h> |
14 | #include <asm/string.h> |
15 | |
16 | u8 purgatory_sha256_digest[SHA256_DIGEST_SIZE] __section(".kexec-purgatory"); |
17 | |
18 | struct kexec_sha_region purgatory_sha_regions[KEXEC_SEGMENT_MAX] __section(".kexec-purgatory"); |
19 | |
20 | static int verify_sha256_digest(void) |
21 | { |
22 | struct kexec_sha_region *ptr, *end; |
23 | struct sha256_state ss; |
24 | u8 digest[SHA256_DIGEST_SIZE]; |
25 | |
26 | sha256_init(sctx: &ss); |
27 | end = purgatory_sha_regions + ARRAY_SIZE(purgatory_sha_regions); |
28 | for (ptr = purgatory_sha_regions; ptr < end; ptr++) |
29 | sha256_update(sctx: &ss, data: (uint8_t *)(ptr->start), len: ptr->len); |
30 | sha256_final(sctx: &ss, out: digest); |
31 | if (memcmp(p: digest, q: purgatory_sha256_digest, size: sizeof(digest)) != 0) |
32 | return 1; |
33 | return 0; |
34 | } |
35 | |
36 | /* workaround for a warning with -Wmissing-prototypes */ |
37 | void purgatory(void); |
38 | |
39 | void purgatory(void) |
40 | { |
41 | if (verify_sha256_digest()) |
42 | for (;;) |
43 | /* loop forever */ |
44 | ; |
45 | } |
46 |