This project aims to create the infrastructure needed to audit crypto operations performed by crypto libraries on a system. This is accomplished by using BPF USDT probes to intercept specific entry points in crypto libraries, as they are used by user space processes on the system, and collect data so that it can be analyzed later.
The design documents can be found from the following links:
- Objectives and high-level design
- Architecture
- Logging format for primary event logs
- USDT probe points
- Install the latest Rust toolchain
- Install the dependencies (note that libbpf 1.1.1 or later is required)
$ sudo dnf install bpftool make libbpf-devel llvm-devel rustfmt
- Build the programs with
make
$ make
The first step requires agent/src/bpf/vmlinux.h
to be populated. By
default it is done through BTF dump from the running kernel with
bpftool
, but if it is not supported in your system, it is possible
to use vmlinux.h
included in the kernel-devel
package:
$ sudo dnf install kernel-devel
$ cp $(rpm -ql kernel-devel | grep '/vmlinux.h$' | tail -1) agent/src/bpf
- Install the programs with
make install
(optional)
$ sudo make install
- Compile the target crypto library with defined tracepoints are enabled
$ git clone --depth=1 -b wip/dueno/usdt https://gitlab.com/dueno/gnutls.git
$ ./bootstrap
$ ./configure
$ make -j$(nproc)
- Run the agent as root
$ sudo ./target/debug/crypto-auditing-agent --library .../gnutls/lib/.libs/libgnutls.so.30.34.2
- On another terminal, run any commands using the instrumented library
$ ./src/gnutls-serv --x509certfile=doc/credentials/x509/cert-rsa-pss.pem --x509keyfile=doc/credentials/x509/key-rsa-pss.pem &
$ ./src/gnutls-cli --x509cafile=doc/credentials/x509/ca.pem localhost -p 5556
^C
$ ./src/gnutls-cli --x509cafile=doc/credentials/x509/ca.pem localhost -p 5556 --priority NORMAL:-VERS-TLS1.3
By default, the log will be stored in audit.cborseq
in a sequence of
CBOR objects, which can be parsed and printed as a tree with the
log_parser
executable:
$ cargo run --bin crypto-auditing-log-parser audit.cborseq
[
{
"context": "66cbb84ee07b90427845ee3d1ae087ba",
"events": {
"name": "tls::handshake_client",
"tls::ciphersuite": 4866,
"tls::protocol_version": 772
},
"map": [
[
"cc337d853f445ad282f4f2a0aec310d8",
{
"context": "cc337d853f445ad282f4f2a0aec310d8",
"events": {
"name": "tls::certificate_verify",
"tls::signature_algorithm": 2057
}
}
]
]
},
{
"context": "2b87eeaf728e24e17ddb8de38d9a7925",
"events": {
"name": "tls::handshake_server",
"tls::ciphersuite": 4866,
"tls::protocol_version": 772
},
"map": [
[
"33650fafec0364c22fa284cbe9c5b809",
{
"context": "33650fafec0364c22fa284cbe9c5b809",
"events": {
"name": "tls::certificate_verify",
"tls::signature_algorithm": 2057
}
}
]
]
},
{
"context": "56ef62bf96e87513e789538e9b880826",
"events": {
"name": "tls::handshake_client",
"tls::ciphersuite": 49200,
"tls::protocol_version": 771
},
"map": [
[
"7bcae3d1a6058293dd634220b266827f",
{
"context": "7bcae3d1a6058293dd634220b266827f",
"events": {
"name": "tls::certificate_verify",
"tls::signature_algorithm": 2057
}
}
]
]
},
{
"context": "2b87eeaf728e24e17ddb8de38d9a7925",
"events": {
"name": "tls::handshake_server",
"tls::ciphersuite": 49200,
"tls::protocol_version": 771
},
"map": [
[
"0c6044428c70bc8678c5035d9a2eed37",
{
"context": "0c6044428c70bc8678c5035d9a2eed37",
"events": {
"name": "tls::certificate_verify",
"tls::signature_algorithm": 2057
}
}
]
]
}
]
To simply deserialize it, you can use the cborseq2json.rb
script
from cbor-diag package, which can
be installed with gem install --user cbor-diag
.
agent/src/bpf/audit.bpf.c
: GPL-2.0-or-lateragent/src/ringbuf.rs
: LGPL-2.1-only or BSD-2-Clause- everything else: GPL-3.0-or-later
- libbpf-async for asynchronous BPF ringbuf implementation over libbpf-rs
- rust-keylime for permissions management code