1 /******************************************************************************
2  *
3  * Module Name: utcksum - Support generating table checksums
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2022, 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
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
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
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
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