forked from fwupd/fwupd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fu-crc.c
146 lines (137 loc) · 2.87 KB
/
fu-crc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
* Copyright (C) 2017 Richard Hughes <[email protected]>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#define G_LOG_DOMAIN "FuCommon"
#include "config.h"
#include "fu-crc.h"
/**
* fu_crc8_full:
* @buf: memory buffer
* @bufsz: size of @buf
* @crc_init: initial CRC value, typically 0x00
* @polynomial: CRC polynomial, e.g. 0x07 for CCITT
*
* Returns the cyclic redundancy check value for the given memory buffer.
*
* Returns: CRC value
*
* Since: 1.8.2
**/
guint8
fu_crc8_full(const guint8 *buf, gsize bufsz, guint8 crc_init, guint8 polynomial)
{
guint32 crc = crc_init;
for (gsize j = bufsz; j > 0; j--) {
crc ^= (*(buf++) << 8);
for (guint32 i = 8; i; i--) {
if (crc & 0x8000)
crc ^= ((polynomial | 0x100) << 7);
crc <<= 1;
}
}
return ~((guint8)(crc >> 8));
}
/**
* fu_crc8:
* @buf: memory buffer
* @bufsz: size of @buf
*
* Returns the cyclic redundancy check value for the given memory buffer.
*
* Returns: CRC value
*
* Since: 1.8.2
**/
guint8
fu_crc8(const guint8 *buf, gsize bufsz)
{
return fu_crc8_full(buf, bufsz, 0x00, 0x07);
}
/**
* fu_crc16_full:
* @buf: memory buffer
* @bufsz: size of @buf
* @crc: initial CRC value, typically 0xFFFF
* @polynomial: CRC polynomial, typically 0xA001 for IBM or 0x1021 for CCITT
*
* Returns the cyclic redundancy check value for the given memory buffer.
*
* Returns: CRC value
*
* Since: 1.8.2
**/
guint16
fu_crc16_full(const guint8 *buf, gsize bufsz, guint16 crc, guint16 polynomial)
{
for (gsize len = bufsz; len > 0; len--) {
crc = (guint16)(crc ^ (*buf++));
for (guint8 i = 0; i < 8; i++) {
if (crc & 0x1) {
crc = (crc >> 1) ^ polynomial;
} else {
crc >>= 1;
}
}
}
return ~crc;
}
/**
* fu_crc16:
* @buf: memory buffer
* @bufsz: size of @buf
*
* Returns the CRC-16-IBM cyclic redundancy value for the given memory buffer.
*
* Returns: CRC value
*
* Since: 1.8.2
**/
guint16
fu_crc16(const guint8 *buf, gsize bufsz)
{
return fu_crc16_full(buf, bufsz, 0xFFFF, 0xA001);
}
/**
* fu_crc32_full:
* @buf: memory buffer
* @bufsz: size of @buf
* @crc: initial CRC value, typically 0xFFFFFFFF
* @polynomial: CRC polynomial, typically 0xEDB88320
*
* Returns the cyclic redundancy check value for the given memory buffer.
*
* Returns: CRC value
*
* Since: 1.8.2
**/
guint32
fu_crc32_full(const guint8 *buf, gsize bufsz, guint32 crc, guint32 polynomial)
{
for (guint32 idx = 0; idx < bufsz; idx++) {
guint8 data = *buf++;
crc = crc ^ data;
for (guint32 bit = 0; bit < 8; bit++) {
guint32 mask = -(crc & 1);
crc = (crc >> 1) ^ (polynomial & mask);
}
}
return ~crc;
}
/**
* fu_crc32:
* @buf: memory buffer
* @bufsz: size of @buf
*
* Returns the cyclic redundancy check value for the given memory buffer.
*
* Returns: CRC value
*
* Since: 1.8.2
**/
guint32
fu_crc32(const guint8 *buf, gsize bufsz)
{
return fu_crc32_full(buf, bufsz, 0xFFFFFFFF, 0xEDB88320);
}