1 /******************************************************************************
2 *
3 * Module Name: utcksum - Support generating table checksums
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2023, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44 #include "acpi.h"
45 #include "accommon.h"
46 #include "acdisasm.h"
47 #include "acutils.h"
48
49
50 /* This module used for application-level code only */
51
52 #define _COMPONENT ACPI_CA_DISASSEMBLER
53 ACPI_MODULE_NAME ("utcksum")
54
55
56 /*******************************************************************************
57 *
58 * FUNCTION: AcpiUtVerifyChecksum
59 *
60 * PARAMETERS: Table - ACPI table to verify
61 * Length - Length of entire table
62 *
63 * RETURN: Status
64 *
65 * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
66 * exception on bad checksum.
67 * Note: We don't have to check for a CDAT here, since CDAT is
68 * not in the RSDT/XSDT, and the CDAT table is never installed
69 * via ACPICA.
70 *
71 ******************************************************************************/
72
73 ACPI_STATUS
AcpiUtVerifyChecksum(ACPI_TABLE_HEADER * Table,UINT32 Length)74 AcpiUtVerifyChecksum (
75 ACPI_TABLE_HEADER *Table,
76 UINT32 Length)
77 {
78 UINT8 Checksum;
79
80
81 /*
82 * FACS/S3PT:
83 * They are the odd tables, have no standard ACPI header and no checksum
84 */
85 if (ACPI_COMPARE_NAMESEG (Table->Signature, ACPI_SIG_S3PT) ||
86 ACPI_COMPARE_NAMESEG (Table->Signature, ACPI_SIG_FACS))
87 {
88 return (AE_OK);
89 }
90
91 /* Compute the checksum on the table */
92
93 Length = Table->Length;
94 Checksum = AcpiUtGenerateChecksum (ACPI_CAST_PTR (UINT8, Table), Length, Table->Checksum);
95
96 /* Computed checksum matches table? */
97
98 if (Checksum != Table->Checksum)
99 {
100 ACPI_BIOS_WARNING ((AE_INFO,
101 "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
102 "should be 0x%2.2X",
103 Table->Signature, Table->Checksum,
104 Table->Checksum - Checksum));
105
106 #if (ACPI_CHECKSUM_ABORT)
107 return (AE_BAD_CHECKSUM);
108 #endif
109 }
110
111 return (AE_OK);
112 }
113
114
115 /*******************************************************************************
116 *
117 * FUNCTION: AcpiUtVerifyCdatChecksum
118 *
119 * PARAMETERS: Table - CDAT ACPI table to verify
120 * Length - Length of entire table
121 *
122 * RETURN: Status
123 *
124 * DESCRIPTION: Verifies that the CDAT table checksums to zero. Optionally
125 * returns an exception on bad checksum.
126 *
127 ******************************************************************************/
128
129 ACPI_STATUS
AcpiUtVerifyCdatChecksum(ACPI_TABLE_CDAT * CdatTable,UINT32 Length)130 AcpiUtVerifyCdatChecksum (
131 ACPI_TABLE_CDAT *CdatTable,
132 UINT32 Length)
133 {
134 UINT8 Checksum;
135
136
137 /* Compute the checksum on the table */
138
139 Checksum = AcpiUtGenerateChecksum (ACPI_CAST_PTR (UINT8, CdatTable),
140 CdatTable->Length, CdatTable->Checksum);
141
142 /* Computed checksum matches table? */
143
144 if (Checksum != CdatTable->Checksum)
145 {
146 ACPI_BIOS_WARNING ((AE_INFO,
147 "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
148 "should be 0x%2.2X",
149 AcpiGbl_CDAT, CdatTable->Checksum, Checksum));
150
151 #if (ACPI_CHECKSUM_ABORT)
152 return (AE_BAD_CHECKSUM);
153 #endif
154 }
155
156 CdatTable->Checksum = Checksum;
157 return (AE_OK);
158 }
159
160
161 /*******************************************************************************
162 *
163 * FUNCTION: AcpiUtGenerateChecksum
164 *
165 * PARAMETERS: Table - Pointer to table to be checksummed
166 * Length - Length of the table
167 * OriginalChecksum - Value of the checksum field
168 *
169 * RETURN: 8 bit checksum of buffer
170 *
171 * DESCRIPTION: Computes an 8 bit checksum of the table.
172 *
173 ******************************************************************************/
174
175 UINT8
AcpiUtGenerateChecksum(void * Table,UINT32 Length,UINT8 OriginalChecksum)176 AcpiUtGenerateChecksum (
177 void *Table,
178 UINT32 Length,
179 UINT8 OriginalChecksum)
180 {
181 UINT8 Checksum;
182
183
184 /* Sum the entire table as-is */
185
186 Checksum = AcpiUtChecksum ((UINT8 *) Table, Length);
187
188 /* Subtract off the existing checksum value in the table */
189
190 Checksum = (UINT8) (Checksum - OriginalChecksum);
191
192 /* Compute and return the final checksum */
193
194 Checksum = (UINT8) (0 - Checksum);
195 return (Checksum);
196 }
197
198
199 /*******************************************************************************
200 *
201 * FUNCTION: AcpiUtChecksum
202 *
203 * PARAMETERS: Buffer - Pointer to memory region to be checked
204 * Length - Length of this memory region
205 *
206 * RETURN: Checksum (UINT8)
207 *
208 * DESCRIPTION: Calculates circular checksum of memory region.
209 *
210 ******************************************************************************/
211
212 UINT8
AcpiUtChecksum(UINT8 * Buffer,UINT32 Length)213 AcpiUtChecksum (
214 UINT8 *Buffer,
215 UINT32 Length)
216 {
217 UINT8 Sum = 0;
218 UINT8 *End = Buffer + Length;
219
220
221 while (Buffer < End)
222 {
223 Sum = (UINT8) (Sum + *(Buffer++));
224 }
225
226 return (Sum);
227 }
228