cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xfs_cksum.h (2372B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef _XFS_CKSUM_H
      3#define _XFS_CKSUM_H 1
      4
      5#define XFS_CRC_SEED	(~(uint32_t)0)
      6
      7/*
      8 * Calculate the intermediate checksum for a buffer that has the CRC field
      9 * inside it.  The offset of the 32bit crc fields is passed as the
     10 * cksum_offset parameter. We do not modify the buffer during verification,
     11 * hence we have to split the CRC calculation across the cksum_offset.
     12 */
     13static inline uint32_t
     14xfs_start_cksum_safe(char *buffer, size_t length, unsigned long cksum_offset)
     15{
     16	uint32_t zero = 0;
     17	uint32_t crc;
     18
     19	/* Calculate CRC up to the checksum. */
     20	crc = crc32c(XFS_CRC_SEED, buffer, cksum_offset);
     21
     22	/* Skip checksum field */
     23	crc = crc32c(crc, &zero, sizeof(__u32));
     24
     25	/* Calculate the rest of the CRC. */
     26	return crc32c(crc, &buffer[cksum_offset + sizeof(__be32)],
     27		      length - (cksum_offset + sizeof(__be32)));
     28}
     29
     30/*
     31 * Fast CRC method where the buffer is modified. Callers must have exclusive
     32 * access to the buffer while the calculation takes place.
     33 */
     34static inline uint32_t
     35xfs_start_cksum_update(char *buffer, size_t length, unsigned long cksum_offset)
     36{
     37	/* zero the CRC field */
     38	*(__le32 *)(buffer + cksum_offset) = 0;
     39
     40	/* single pass CRC calculation for the entire buffer */
     41	return crc32c(XFS_CRC_SEED, buffer, length);
     42}
     43
     44/*
     45 * Convert the intermediate checksum to the final ondisk format.
     46 *
     47 * The CRC32c calculation uses LE format even on BE machines, but returns the
     48 * result in host endian format. Hence we need to byte swap it back to LE format
     49 * so that it is consistent on disk.
     50 */
     51static inline __le32
     52xfs_end_cksum(uint32_t crc)
     53{
     54	return ~cpu_to_le32(crc);
     55}
     56
     57/*
     58 * Helper to generate the checksum for a buffer.
     59 *
     60 * This modifies the buffer temporarily - callers must have exclusive
     61 * access to the buffer while the calculation takes place.
     62 */
     63static inline void
     64xfs_update_cksum(char *buffer, size_t length, unsigned long cksum_offset)
     65{
     66	uint32_t crc = xfs_start_cksum_update(buffer, length, cksum_offset);
     67
     68	*(__le32 *)(buffer + cksum_offset) = xfs_end_cksum(crc);
     69}
     70
     71/*
     72 * Helper to verify the checksum for a buffer.
     73 */
     74static inline int
     75xfs_verify_cksum(char *buffer, size_t length, unsigned long cksum_offset)
     76{
     77	uint32_t crc = xfs_start_cksum_safe(buffer, length, cksum_offset);
     78
     79	return *(__le32 *)(buffer + cksum_offset) == xfs_end_cksum(crc);
     80}
     81
     82#endif /* _XFS_CKSUM_H */