Commit | Line | Data |
---|---|---|
8fc5b4d4 VG |
1 | /* |
2 | * purgatory: Runs between two kernels | |
3 | * | |
4 | * Copyright (C) 2014 Red Hat Inc. | |
5 | * | |
6 | * Author: | |
7 | * Vivek Goyal <vgoyal@redhat.com> | |
8 | * | |
9 | * This source code is licensed under the GNU General Public License, | |
10 | * Version 2. See the file COPYING for more details. | |
11 | */ | |
12 | ||
13 | #include "sha256.h" | |
14 | #include "../boot/string.h" | |
15 | ||
16 | struct sha_region { | |
17 | unsigned long start; | |
18 | unsigned long len; | |
19 | }; | |
20 | ||
21 | unsigned long backup_dest = 0; | |
22 | unsigned long backup_src = 0; | |
23 | unsigned long backup_sz = 0; | |
24 | ||
25 | u8 sha256_digest[SHA256_DIGEST_SIZE] = { 0 }; | |
26 | ||
27 | struct sha_region sha_regions[16] = {}; | |
28 | ||
29 | /* | |
30 | * On x86, second kernel requries first 640K of memory to boot. Copy | |
31 | * first 640K to a backup region in reserved memory range so that second | |
32 | * kernel can use first 640K. | |
33 | */ | |
34 | static int copy_backup_region(void) | |
35 | { | |
36 | if (backup_dest) | |
37 | memcpy((void *)backup_dest, (void *)backup_src, backup_sz); | |
38 | ||
39 | return 0; | |
40 | } | |
41 | ||
42 | int verify_sha256_digest(void) | |
43 | { | |
44 | struct sha_region *ptr, *end; | |
45 | u8 digest[SHA256_DIGEST_SIZE]; | |
46 | struct sha256_state sctx; | |
47 | ||
48 | sha256_init(&sctx); | |
49 | end = &sha_regions[sizeof(sha_regions)/sizeof(sha_regions[0])]; | |
50 | for (ptr = sha_regions; ptr < end; ptr++) | |
51 | sha256_update(&sctx, (uint8_t *)(ptr->start), ptr->len); | |
52 | ||
53 | sha256_final(&sctx, digest); | |
54 | ||
55 | if (memcmp(digest, sha256_digest, sizeof(digest))) | |
56 | return 1; | |
57 | ||
58 | return 0; | |
59 | } | |
60 | ||
61 | void purgatory(void) | |
62 | { | |
63 | int ret; | |
64 | ||
65 | ret = verify_sha256_digest(); | |
66 | if (ret) { | |
67 | /* loop forever */ | |
68 | for (;;) | |
69 | ; | |
70 | } | |
71 | copy_backup_region(); | |
72 | } |