1*d289c2baSAndroid Build Coastguard Worker /*
2*d289c2baSAndroid Build Coastguard Worker * Copyright 2020 The Android Open Source Project
3*d289c2baSAndroid Build Coastguard Worker *
4*d289c2baSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*d289c2baSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*d289c2baSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*d289c2baSAndroid Build Coastguard Worker *
8*d289c2baSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*d289c2baSAndroid Build Coastguard Worker *
10*d289c2baSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*d289c2baSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*d289c2baSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d289c2baSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*d289c2baSAndroid Build Coastguard Worker * limitations under the License.
15*d289c2baSAndroid Build Coastguard Worker */
16*d289c2baSAndroid Build Coastguard Worker
17*d289c2baSAndroid Build Coastguard Worker /* See https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks
18*d289c2baSAndroid Build Coastguard Worker * for info on the general algorithm. We use the following configuration:
19*d289c2baSAndroid Build Coastguard Worker * 32-bit CRC
20*d289c2baSAndroid Build Coastguard Worker * Polynomial = 0x04C11DB7
21*d289c2baSAndroid Build Coastguard Worker * MSB-first
22*d289c2baSAndroid Build Coastguard Worker * Input and output complement
23*d289c2baSAndroid Build Coastguard Worker * Input and output bit reversal
24*d289c2baSAndroid Build Coastguard Worker *
25*d289c2baSAndroid Build Coastguard Worker * This implementation optimizes for size and readability. We only need this for
26*d289c2baSAndroid Build Coastguard Worker * 28 bytes of A/B booting metadata, so efficiency is largely irrelevant whereas
27*d289c2baSAndroid Build Coastguard Worker * a 1KiB lookup table can be a significant cost for bootloaders.
28*d289c2baSAndroid Build Coastguard Worker */
29*d289c2baSAndroid Build Coastguard Worker
30*d289c2baSAndroid Build Coastguard Worker #include "avb_util.h"
31*d289c2baSAndroid Build Coastguard Worker
32*d289c2baSAndroid Build Coastguard Worker /* Lookup table for reversing 4 bits. */
33*d289c2baSAndroid Build Coastguard Worker /* clang-format off */
34*d289c2baSAndroid Build Coastguard Worker static uint8_t reverse_4bit_table[] = {
35*d289c2baSAndroid Build Coastguard Worker 0x0, 0x8, 0x4, 0xC,
36*d289c2baSAndroid Build Coastguard Worker 0x2, 0xA, 0x6, 0xE,
37*d289c2baSAndroid Build Coastguard Worker 0x1, 0x9, 0x5, 0xD,
38*d289c2baSAndroid Build Coastguard Worker 0x3, 0xB, 0x7, 0xF
39*d289c2baSAndroid Build Coastguard Worker };
40*d289c2baSAndroid Build Coastguard Worker /* clang-format on */
41*d289c2baSAndroid Build Coastguard Worker
reverse_byte(uint8_t val)42*d289c2baSAndroid Build Coastguard Worker static uint8_t reverse_byte(uint8_t val) {
43*d289c2baSAndroid Build Coastguard Worker return (reverse_4bit_table[val & 0xF] << 4) | reverse_4bit_table[val >> 4];
44*d289c2baSAndroid Build Coastguard Worker }
45*d289c2baSAndroid Build Coastguard Worker
reverse_uint32(uint32_t val)46*d289c2baSAndroid Build Coastguard Worker static uint32_t reverse_uint32(uint32_t val) {
47*d289c2baSAndroid Build Coastguard Worker return (reverse_byte(val) << 24) | (reverse_byte(val >> 8) << 16) |
48*d289c2baSAndroid Build Coastguard Worker (reverse_byte(val >> 16) << 8) | reverse_byte(val >> 24);
49*d289c2baSAndroid Build Coastguard Worker }
50*d289c2baSAndroid Build Coastguard Worker
avb_crc32(const uint8_t * buf,size_t size)51*d289c2baSAndroid Build Coastguard Worker uint32_t avb_crc32(const uint8_t* buf, size_t size) {
52*d289c2baSAndroid Build Coastguard Worker uint32_t crc = 0xFFFFFFFF;
53*d289c2baSAndroid Build Coastguard Worker
54*d289c2baSAndroid Build Coastguard Worker for (size_t i = 0; i < size; ++i) {
55*d289c2baSAndroid Build Coastguard Worker crc = crc ^ ((uint32_t)reverse_byte(buf[i]) << 24);
56*d289c2baSAndroid Build Coastguard Worker for (int j = 0; j < 8; ++j) {
57*d289c2baSAndroid Build Coastguard Worker if (crc & 0x80000000) {
58*d289c2baSAndroid Build Coastguard Worker crc = (crc << 1) ^ 0x04C11DB7;
59*d289c2baSAndroid Build Coastguard Worker } else {
60*d289c2baSAndroid Build Coastguard Worker crc <<= 1;
61*d289c2baSAndroid Build Coastguard Worker }
62*d289c2baSAndroid Build Coastguard Worker }
63*d289c2baSAndroid Build Coastguard Worker }
64*d289c2baSAndroid Build Coastguard Worker
65*d289c2baSAndroid Build Coastguard Worker return reverse_uint32(~crc);
66*d289c2baSAndroid Build Coastguard Worker }
67