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

checksum.c (2598B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Network checksum routines
      4 *
      5 * Copyright (C) 1999, 2003 Hewlett-Packard Co
      6 *	Stephane Eranian <eranian@hpl.hp.com>
      7 *
      8 * Most of the code coming from arch/alpha/lib/checksum.c
      9 *
     10 * This file contains network checksum routines that are better done
     11 * in an architecture-specific manner due to speed..
     12 */
     13
     14#include <linux/module.h>
     15#include <linux/string.h>
     16
     17#include <asm/byteorder.h>
     18
     19static inline unsigned short
     20from64to16 (unsigned long x)
     21{
     22	/* add up 32-bit words for 33 bits */
     23	x = (x & 0xffffffff) + (x >> 32);
     24	/* add up 16-bit and 17-bit words for 17+c bits */
     25	x = (x & 0xffff) + (x >> 16);
     26	/* add up 16-bit and 2-bit for 16+c bit */
     27	x = (x & 0xffff) + (x >> 16);
     28	/* add up carry.. */
     29	x = (x & 0xffff) + (x >> 16);
     30	return x;
     31}
     32
     33/*
     34 * computes the checksum of the TCP/UDP pseudo-header
     35 * returns a 16-bit checksum, already complemented.
     36 */
     37__sum16
     38csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
     39		  __u8 proto, __wsum sum)
     40{
     41	return (__force __sum16)~from64to16(
     42		(__force u64)saddr + (__force u64)daddr +
     43		(__force u64)sum + ((len + proto) << 8));
     44}
     45
     46EXPORT_SYMBOL(csum_tcpudp_magic);
     47
     48__wsum
     49csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
     50		   __u8 proto, __wsum sum)
     51{
     52	unsigned long result;
     53
     54	result = (__force u64)saddr + (__force u64)daddr +
     55		 (__force u64)sum + ((len + proto) << 8);
     56
     57	/* Fold down to 32-bits so we don't lose in the typedef-less network stack.  */
     58	/* 64 to 33 */
     59	result = (result & 0xffffffff) + (result >> 32);
     60	/* 33 to 32 */
     61	result = (result & 0xffffffff) + (result >> 32);
     62	return (__force __wsum)result;
     63}
     64EXPORT_SYMBOL(csum_tcpudp_nofold);
     65
     66extern unsigned long do_csum (const unsigned char *, long);
     67
     68/*
     69 * computes the checksum of a memory block at buff, length len,
     70 * and adds in "sum" (32-bit)
     71 *
     72 * returns a 32-bit number suitable for feeding into itself
     73 * or csum_tcpudp_magic
     74 *
     75 * this function must be called with even lengths, except
     76 * for the last fragment, which may be odd
     77 *
     78 * it's best to have buff aligned on a 32-bit boundary
     79 */
     80__wsum csum_partial(const void *buff, int len, __wsum sum)
     81{
     82	u64 result = do_csum(buff, len);
     83
     84	/* add in old sum, and carry.. */
     85	result += (__force u32)sum;
     86	/* 32+c bits -> 32 bits */
     87	result = (result & 0xffffffff) + (result >> 32);
     88	return (__force __wsum)result;
     89}
     90
     91EXPORT_SYMBOL(csum_partial);
     92
     93/*
     94 * this routine is used for miscellaneous IP-like checksums, mainly
     95 * in icmp.c
     96 */
     97__sum16 ip_compute_csum (const void *buff, int len)
     98{
     99	return (__force __sum16)~do_csum(buff,len);
    100}
    101
    102EXPORT_SYMBOL(ip_compute_csum);