Hello David, On Mon, May 10, 2021 at 01:38:49PM +0000, David Laight wrote: > > replace private CRC-32 routines with in-kernel ones. > > Have you verified that they compute the same CRC? > > There are all sorts of subtle reasons why the outputs can differ. > > David > > - > Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK > Registration No: 1397386 (Wales) > I tried this: #include <linux/module.h> #include <linux/crc32poly.h> #include <linux/crc32.h> /* Copy pasted from rtl8723bs/core/rtw_security.c */ static signed int bcrc32initialized; static u32 crc32_table[256]; MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CRC-32 verifier"); MODULE_AUTHOR("Fabio Aiuto"); /* Copy pasted from rtl8723bs/core/rtw_security.c */ static u8 crc32_reverseBit(u8 data) { return ((u8)((data<<7)&0x80) | ((data<<5)&0x40) | ((data<<3)&0x20) | ((data<<1)&0x10) | ((data>>1)&0x08) | ((data>>3)&0x04) | ((data>>5)&0x02) | ((data>>7)&0x01)); } /* Copy pasted from rtl8723bs/core/rtw_security.c */ static void crc32_init(void) { if (bcrc32initialized == 1) return; else { signed int i, j; u32 c; u8 *p = (u8 *)&c, *p1; u8 k; c = 0x12340000; for (i = 0; i < 256; ++i) { k = crc32_reverseBit((u8)i); for (c = ((u32)k) << 24, j = 8; j > 0; --j) c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY_BE : (c << 1); p1 = (u8 *)&crc32_table[i]; p1[0] = crc32_reverseBit(p[3]); p1[1] = crc32_reverseBit(p[2]); p1[2] = crc32_reverseBit(p[1]); p1[3] = crc32_reverseBit(p[0]); } bcrc32initialized = 1; } } /* Copy pasted from rtl8723bs/core/rtw_security.c */ static __le32 getcrc32(u8 *buf, signed int len) { u8 *p; u32 crc; if (bcrc32initialized == 0) crc32_init(); crc = 0xffffffff; /* preload shift register, per CRC-32 spec */ for (p = buf; len > 0; ++p, --len) crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8); return cpu_to_le32(~crc); /* transmit complement, per CRC-32 spec */ } static int __init crc32_entry(void) { u8 payload; unsigned char crc_priv[4], crc_pub[4]; payload = (u8)1234; /* private crc calculation used in rtl8723bs */ *((__le32 *)crc_priv) = getcrc32(&payload, 2); pr_info("private rtl8723bs crc: %x", *crc_priv); /* in-kernel public crc calculation */ *((__le32 *)crc_pub) = ~crc32_le(~0, &payload, 2); pr_info("generic crc: %x", *crc_pub); return 0; } static void __exit crc32_exit(void) { } module_init(crc32_entry); module_exit(crc32_exit); And run it on qemu. Don't know why to display the second pr_info() I have to rmmod it, but both methods give the same result (62) [ 38.149979] crc32m: module is from the staging directory, the quality is unknown, you have been warned. [ 38.169208] private rtl8723bs crc: 62 [ 38.169400] generic crc: 62 thank you, fabio