Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/lib/bpf/libbpf_utils.c
29524 views
1
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2
3
/*
4
* Copyright (C) 2013-2015 Alexei Starovoitov <[email protected]>
5
* Copyright (C) 2015 Wang Nan <[email protected]>
6
* Copyright (C) 2015 Huawei Inc.
7
* Copyright (C) 2017 Nicira, Inc.
8
*/
9
10
#undef _GNU_SOURCE
11
#include <stdio.h>
12
#include <string.h>
13
#include <errno.h>
14
#include <inttypes.h>
15
#include <linux/kernel.h>
16
17
#include "libbpf.h"
18
#include "libbpf_internal.h"
19
20
#ifndef ENOTSUPP
21
#define ENOTSUPP 524
22
#endif
23
24
/* make sure libbpf doesn't use kernel-only integer typedefs */
25
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
26
27
#define ERRNO_OFFSET(e) ((e) - __LIBBPF_ERRNO__START)
28
#define ERRCODE_OFFSET(c) ERRNO_OFFSET(LIBBPF_ERRNO__##c)
29
#define NR_ERRNO (__LIBBPF_ERRNO__END - __LIBBPF_ERRNO__START)
30
31
static const char *libbpf_strerror_table[NR_ERRNO] = {
32
[ERRCODE_OFFSET(LIBELF)] = "Something wrong in libelf",
33
[ERRCODE_OFFSET(FORMAT)] = "BPF object format invalid",
34
[ERRCODE_OFFSET(KVERSION)] = "'version' section incorrect or lost",
35
[ERRCODE_OFFSET(ENDIAN)] = "Endian mismatch",
36
[ERRCODE_OFFSET(INTERNAL)] = "Internal error in libbpf",
37
[ERRCODE_OFFSET(RELOC)] = "Relocation failed",
38
[ERRCODE_OFFSET(VERIFY)] = "Kernel verifier blocks program loading",
39
[ERRCODE_OFFSET(PROG2BIG)] = "Program too big",
40
[ERRCODE_OFFSET(KVER)] = "Incorrect kernel version",
41
[ERRCODE_OFFSET(PROGTYPE)] = "Kernel doesn't support this program type",
42
[ERRCODE_OFFSET(WRNGPID)] = "Wrong pid in netlink message",
43
[ERRCODE_OFFSET(INVSEQ)] = "Invalid netlink sequence",
44
[ERRCODE_OFFSET(NLPARSE)] = "Incorrect netlink message parsing",
45
};
46
47
int libbpf_strerror(int err, char *buf, size_t size)
48
{
49
int ret;
50
51
if (!buf || !size)
52
return libbpf_err(-EINVAL);
53
54
err = err > 0 ? err : -err;
55
56
if (err < __LIBBPF_ERRNO__START) {
57
ret = strerror_r(err, buf, size);
58
buf[size - 1] = '\0';
59
return libbpf_err_errno(ret);
60
}
61
62
if (err < __LIBBPF_ERRNO__END) {
63
const char *msg;
64
65
msg = libbpf_strerror_table[ERRNO_OFFSET(err)];
66
ret = snprintf(buf, size, "%s", msg);
67
buf[size - 1] = '\0';
68
/* The length of the buf and msg is positive.
69
* A negative number may be returned only when the
70
* size exceeds INT_MAX. Not likely to appear.
71
*/
72
if (ret >= size)
73
return libbpf_err(-ERANGE);
74
return 0;
75
}
76
77
ret = snprintf(buf, size, "Unknown libbpf error %d", err);
78
buf[size - 1] = '\0';
79
if (ret >= size)
80
return libbpf_err(-ERANGE);
81
return libbpf_err(-ENOENT);
82
}
83
84
const char *libbpf_errstr(int err)
85
{
86
static __thread char buf[12];
87
88
if (err > 0)
89
err = -err;
90
91
switch (err) {
92
case -E2BIG: return "-E2BIG";
93
case -EACCES: return "-EACCES";
94
case -EADDRINUSE: return "-EADDRINUSE";
95
case -EADDRNOTAVAIL: return "-EADDRNOTAVAIL";
96
case -EAGAIN: return "-EAGAIN";
97
case -EALREADY: return "-EALREADY";
98
case -EBADF: return "-EBADF";
99
case -EBADFD: return "-EBADFD";
100
case -EBUSY: return "-EBUSY";
101
case -ECANCELED: return "-ECANCELED";
102
case -ECHILD: return "-ECHILD";
103
case -EDEADLK: return "-EDEADLK";
104
case -EDOM: return "-EDOM";
105
case -EEXIST: return "-EEXIST";
106
case -EFAULT: return "-EFAULT";
107
case -EFBIG: return "-EFBIG";
108
case -EILSEQ: return "-EILSEQ";
109
case -EINPROGRESS: return "-EINPROGRESS";
110
case -EINTR: return "-EINTR";
111
case -EINVAL: return "-EINVAL";
112
case -EIO: return "-EIO";
113
case -EISDIR: return "-EISDIR";
114
case -ELOOP: return "-ELOOP";
115
case -EMFILE: return "-EMFILE";
116
case -EMLINK: return "-EMLINK";
117
case -EMSGSIZE: return "-EMSGSIZE";
118
case -ENAMETOOLONG: return "-ENAMETOOLONG";
119
case -ENFILE: return "-ENFILE";
120
case -ENODATA: return "-ENODATA";
121
case -ENODEV: return "-ENODEV";
122
case -ENOENT: return "-ENOENT";
123
case -ENOEXEC: return "-ENOEXEC";
124
case -ENOLINK: return "-ENOLINK";
125
case -ENOMEM: return "-ENOMEM";
126
case -ENOSPC: return "-ENOSPC";
127
case -ENOTBLK: return "-ENOTBLK";
128
case -ENOTDIR: return "-ENOTDIR";
129
case -ENOTSUPP: return "-ENOTSUPP";
130
case -ENOTTY: return "-ENOTTY";
131
case -ENXIO: return "-ENXIO";
132
case -EOPNOTSUPP: return "-EOPNOTSUPP";
133
case -EOVERFLOW: return "-EOVERFLOW";
134
case -EPERM: return "-EPERM";
135
case -EPIPE: return "-EPIPE";
136
case -EPROTO: return "-EPROTO";
137
case -EPROTONOSUPPORT: return "-EPROTONOSUPPORT";
138
case -ERANGE: return "-ERANGE";
139
case -EROFS: return "-EROFS";
140
case -ESPIPE: return "-ESPIPE";
141
case -ESRCH: return "-ESRCH";
142
case -ETXTBSY: return "-ETXTBSY";
143
case -EUCLEAN: return "-EUCLEAN";
144
case -EXDEV: return "-EXDEV";
145
default:
146
snprintf(buf, sizeof(buf), "%d", err);
147
return buf;
148
}
149
}
150
151
#pragma GCC diagnostic push
152
#pragma GCC diagnostic ignored "-Wpacked"
153
#pragma GCC diagnostic ignored "-Wattributes"
154
struct __packed_u32 { __u32 __val; } __attribute__((packed));
155
#pragma GCC diagnostic pop
156
157
#define get_unaligned_be32(p) be32_to_cpu((((struct __packed_u32 *)(p))->__val))
158
#define put_unaligned_be32(v, p) do { \
159
((struct __packed_u32 *)(p))->__val = cpu_to_be32(v); \
160
} while (0)
161
162
#define SHA256_BLOCK_LENGTH 64
163
#define Ch(x, y, z) (((x) & (y)) ^ (~(x) & (z)))
164
#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
165
#define Sigma_0(x) (ror32((x), 2) ^ ror32((x), 13) ^ ror32((x), 22))
166
#define Sigma_1(x) (ror32((x), 6) ^ ror32((x), 11) ^ ror32((x), 25))
167
#define sigma_0(x) (ror32((x), 7) ^ ror32((x), 18) ^ ((x) >> 3))
168
#define sigma_1(x) (ror32((x), 17) ^ ror32((x), 19) ^ ((x) >> 10))
169
170
static const __u32 sha256_K[64] = {
171
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
172
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
173
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
174
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
175
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
176
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
177
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
178
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
179
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
180
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
181
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
182
};
183
184
#define SHA256_ROUND(i, a, b, c, d, e, f, g, h) \
185
{ \
186
__u32 tmp = h + Sigma_1(e) + Ch(e, f, g) + sha256_K[i] + w[i]; \
187
d += tmp; \
188
h = tmp + Sigma_0(a) + Maj(a, b, c); \
189
}
190
191
static void sha256_blocks(__u32 state[8], const __u8 *data, size_t nblocks)
192
{
193
while (nblocks--) {
194
__u32 a = state[0];
195
__u32 b = state[1];
196
__u32 c = state[2];
197
__u32 d = state[3];
198
__u32 e = state[4];
199
__u32 f = state[5];
200
__u32 g = state[6];
201
__u32 h = state[7];
202
__u32 w[64];
203
int i;
204
205
for (i = 0; i < 16; i++)
206
w[i] = get_unaligned_be32(&data[4 * i]);
207
for (; i < ARRAY_SIZE(w); i++)
208
w[i] = sigma_1(w[i - 2]) + w[i - 7] +
209
sigma_0(w[i - 15]) + w[i - 16];
210
for (i = 0; i < ARRAY_SIZE(w); i += 8) {
211
SHA256_ROUND(i + 0, a, b, c, d, e, f, g, h);
212
SHA256_ROUND(i + 1, h, a, b, c, d, e, f, g);
213
SHA256_ROUND(i + 2, g, h, a, b, c, d, e, f);
214
SHA256_ROUND(i + 3, f, g, h, a, b, c, d, e);
215
SHA256_ROUND(i + 4, e, f, g, h, a, b, c, d);
216
SHA256_ROUND(i + 5, d, e, f, g, h, a, b, c);
217
SHA256_ROUND(i + 6, c, d, e, f, g, h, a, b);
218
SHA256_ROUND(i + 7, b, c, d, e, f, g, h, a);
219
}
220
state[0] += a;
221
state[1] += b;
222
state[2] += c;
223
state[3] += d;
224
state[4] += e;
225
state[5] += f;
226
state[6] += g;
227
state[7] += h;
228
data += SHA256_BLOCK_LENGTH;
229
}
230
}
231
232
void libbpf_sha256(const void *data, size_t len, __u8 out[SHA256_DIGEST_LENGTH])
233
{
234
__u32 state[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
235
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
236
const __be64 bitcount = cpu_to_be64((__u64)len * 8);
237
__u8 final_data[2 * SHA256_BLOCK_LENGTH] = { 0 };
238
size_t final_len = len % SHA256_BLOCK_LENGTH;
239
int i;
240
241
sha256_blocks(state, data, len / SHA256_BLOCK_LENGTH);
242
243
memcpy(final_data, data + len - final_len, final_len);
244
final_data[final_len] = 0x80;
245
final_len = roundup(final_len + 9, SHA256_BLOCK_LENGTH);
246
memcpy(&final_data[final_len - 8], &bitcount, 8);
247
248
sha256_blocks(state, final_data, final_len / SHA256_BLOCK_LENGTH);
249
250
for (i = 0; i < ARRAY_SIZE(state); i++)
251
put_unaligned_be32(state[i], &out[4 * i]);
252
}
253
254