Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/lib/bpf/libbpf_utils.c
30363 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
static inline __u32 get_unaligned_be32(const void *p)
152
{
153
__be32 val;
154
155
memcpy(&val, p, sizeof(val));
156
return be32_to_cpu(val);
157
}
158
159
static inline void put_unaligned_be32(__u32 val, void *p)
160
{
161
__be32 be_val = cpu_to_be32(val);
162
163
memcpy(p, &be_val, sizeof(be_val));
164
}
165
166
#define SHA256_BLOCK_LENGTH 64
167
#define Ch(x, y, z) (((x) & (y)) ^ (~(x) & (z)))
168
#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
169
#define Sigma_0(x) (ror32((x), 2) ^ ror32((x), 13) ^ ror32((x), 22))
170
#define Sigma_1(x) (ror32((x), 6) ^ ror32((x), 11) ^ ror32((x), 25))
171
#define sigma_0(x) (ror32((x), 7) ^ ror32((x), 18) ^ ((x) >> 3))
172
#define sigma_1(x) (ror32((x), 17) ^ ror32((x), 19) ^ ((x) >> 10))
173
174
static const __u32 sha256_K[64] = {
175
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
176
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
177
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
178
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
179
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
180
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
181
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
182
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
183
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
184
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
185
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
186
};
187
188
#define SHA256_ROUND(i, a, b, c, d, e, f, g, h) \
189
{ \
190
__u32 tmp = h + Sigma_1(e) + Ch(e, f, g) + sha256_K[i] + w[i]; \
191
d += tmp; \
192
h = tmp + Sigma_0(a) + Maj(a, b, c); \
193
}
194
195
static void sha256_blocks(__u32 state[8], const __u8 *data, size_t nblocks)
196
{
197
while (nblocks--) {
198
__u32 a = state[0];
199
__u32 b = state[1];
200
__u32 c = state[2];
201
__u32 d = state[3];
202
__u32 e = state[4];
203
__u32 f = state[5];
204
__u32 g = state[6];
205
__u32 h = state[7];
206
__u32 w[64];
207
int i;
208
209
for (i = 0; i < 16; i++)
210
w[i] = get_unaligned_be32(&data[4 * i]);
211
for (; i < ARRAY_SIZE(w); i++)
212
w[i] = sigma_1(w[i - 2]) + w[i - 7] +
213
sigma_0(w[i - 15]) + w[i - 16];
214
for (i = 0; i < ARRAY_SIZE(w); i += 8) {
215
SHA256_ROUND(i + 0, a, b, c, d, e, f, g, h);
216
SHA256_ROUND(i + 1, h, a, b, c, d, e, f, g);
217
SHA256_ROUND(i + 2, g, h, a, b, c, d, e, f);
218
SHA256_ROUND(i + 3, f, g, h, a, b, c, d, e);
219
SHA256_ROUND(i + 4, e, f, g, h, a, b, c, d);
220
SHA256_ROUND(i + 5, d, e, f, g, h, a, b, c);
221
SHA256_ROUND(i + 6, c, d, e, f, g, h, a, b);
222
SHA256_ROUND(i + 7, b, c, d, e, f, g, h, a);
223
}
224
state[0] += a;
225
state[1] += b;
226
state[2] += c;
227
state[3] += d;
228
state[4] += e;
229
state[5] += f;
230
state[6] += g;
231
state[7] += h;
232
data += SHA256_BLOCK_LENGTH;
233
}
234
}
235
236
void libbpf_sha256(const void *data, size_t len, __u8 out[SHA256_DIGEST_LENGTH])
237
{
238
__u32 state[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
239
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
240
const __be64 bitcount = cpu_to_be64((__u64)len * 8);
241
__u8 final_data[2 * SHA256_BLOCK_LENGTH] = { 0 };
242
size_t final_len = len % SHA256_BLOCK_LENGTH;
243
int i;
244
245
sha256_blocks(state, data, len / SHA256_BLOCK_LENGTH);
246
247
memcpy(final_data, data + len - final_len, final_len);
248
final_data[final_len] = 0x80;
249
final_len = roundup(final_len + 9, SHA256_BLOCK_LENGTH);
250
memcpy(&final_data[final_len - 8], &bitcount, 8);
251
252
sha256_blocks(state, final_data, final_len / SHA256_BLOCK_LENGTH);
253
254
for (i = 0; i < ARRAY_SIZE(state); i++)
255
put_unaligned_be32(state[i], &out[4 * i]);
256
}
257
258