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 <crypto/sha.h>
13#include <asm/purgatory.h>
14
15#include "../boot/string.h"
16
17u8 purgatory_sha256_digest[SHA256_DIGEST_SIZE] __section(".kexec-purgatory");
18
19struct kexec_sha_region purgatory_sha_regions[KEXEC_SEGMENT_MAX] __section(".kexec-purgatory");
20
21static int verify_sha256_digest(void)
22{
23	struct kexec_sha_region *ptr, *end;
24	u8 digest[SHA256_DIGEST_SIZE];
25	struct sha256_state sctx;
26
27	sha256_init(&sctx);
28	end = purgatory_sha_regions + ARRAY_SIZE(purgatory_sha_regions);
29
30	for (ptr = purgatory_sha_regions; ptr < end; ptr++)
31		sha256_update(&sctx, (uint8_t *)(ptr->start), ptr->len);
32
33	sha256_final(&sctx, digest);
34
35	if (memcmp(digest, purgatory_sha256_digest, sizeof(digest)))
36		return 1;
37
38	return 0;
39}
40
41void purgatory(void)
42{
43	int ret;
44
45	ret = verify_sha256_digest();
46	if (ret) {
47		/* loop forever */
48		for (;;)
49			;
50	}
51}
52
53/*
54 * Defined in order to reuse memcpy() and memset() from
55 * arch/x86/boot/compressed/string.c
56 */
57void warn(const char *msg) {}
58