#ifndef INTERNAL_H
#define INTERNAL_H
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/aio_abi.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/uio.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
#include <linux/if_alg.h>
#include "atomic.h"
#include "kcapi.h"
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef ALG_SET_AEAD_ASSOCLEN
#define ALG_SET_AEAD_ASSOCLEN 4
#endif
#ifndef ALG_SET_AEAD_AUTHSIZE
#define ALG_SET_AEAD_AUTHSIZE 5
#endif
#ifndef ALG_SET_DRBG_ENTROPY
#define ALG_SET_DRBG_ENTROPY 6
#endif
#ifndef ALG_SET_PUBKEY
#define ALG_SET_PUBKEY 7
#endif
#ifndef ALG_SET_DH_PARAMETERS
#define ALG_SET_DH_PARAMETERS 8
#endif
#ifndef ALG_SET_ECDH_CURVE
#define ALG_SET_ECDH_CURVE 9
#endif
#ifndef ALG_OP_SIGN
#define ALG_OP_SIGN 2
#endif
#ifndef ALG_OP_VERIFY
#define ALG_OP_VERIFY 3
#endif
#ifndef ALG_OP_KEYGEN
#define ALG_OP_KEYGEN 4
#endif
#ifndef ALG_OP_SSGEN
#define ALG_OP_SSGEN 5
#endif
#ifndef AF_ALG
#define AF_ALG 38
#endif
#ifndef SOL_ALG
#define SOL_ALG 279
#endif
#ifndef ALG_MAX_PAGES
#define ALG_MAX_PAGES 16
#endif
enum { false, true };
typedef _Bool bool;
enum kcapi_cipher_type {
KCAPI_CIPHER_SKCIPHER,
KCAPI_CIPHER_AEAD,
KCAPI_CIPHER_KDF,
KCAPI_CIPHER_RNG,
KCAPI_CIPHER_MD,
KCAPI_CIPHER_KPP,
KCAPI_CIPHER_AKCIPHER,
};
struct kcapi_cipher_info {
enum kcapi_cipher_type cipher_type;
uint32_t blocksize;
uint32_t ivsize;
uint32_t hash_digestsize;
uint32_t blk_min_keysize;
uint32_t blk_max_keysize;
uint32_t aead_maxauthsize;
uint32_t rng_seedsize;
};
struct kcapi_cipher_data {
const uint8_t *iv;
};
struct kcapi_aead_data {
size_t datalen;
size_t assoclen;
size_t taglen;
uint8_t *data;
uint8_t *assoc;
uint8_t *tag;
};
#define KCAPI_AIO_CONCURRENT 64
#define AIO_OUTSTANDING ((__s64)-(1<<13))
struct kcapi_aio {
bool disable;
int efd;
aio_context_t aio_ctx;
__s64 *iocb_ret;
struct iocb *cio;
struct iocb **ciopp;
};
struct kcapi_flags {
bool ge_v4_9;
uint32_t alg_max_pages;
};
struct kcapi_sys {
unsigned long kernel_maj, kernel_minor, kernel_patchlevel;
};
struct kcapi_handle_tfm {
int tfmfd;
struct kcapi_sys sysinfo;
struct kcapi_cipher_info info;
atomic_t refcnt;
};
struct kcapi_handle {
struct kcapi_handle_tfm *tfm;
int pipes[2];
int opfd;
unsigned int pagesize;
unsigned int pipesize;
size_t processed_sg;
struct kcapi_cipher_data cipher;
struct kcapi_aead_data aead;
struct kcapi_aio aio;
struct kcapi_flags flags;
};
extern enum kcapi_verbosity kcapi_verbosity_level;
void kcapi_dolog(enum kcapi_verbosity severity, const char *fmt, ...);
static inline int *_kcapi_get_opfd(struct kcapi_handle *handle)
{
return &handle->opfd;
}
ssize_t _kcapi_common_send_meta(struct kcapi_handle *handle,
struct iovec *iov, size_t iovlen,
uint32_t enc, uint32_t flags);
ssize_t _kcapi_common_vmsplice_iov(struct kcapi_handle *handle,
struct iovec *iov, size_t iovlen,
uint32_t flags);
ssize_t _kcapi_common_send_data(struct kcapi_handle *handle,
struct iovec *iov, size_t iovlen,
uint32_t flags);
ssize_t _kcapi_common_recv_data(struct kcapi_handle *handle,
struct iovec *iov, size_t iovlen);
ssize_t _kcapi_common_read_data(struct kcapi_handle *handle,
uint8_t *out, size_t outlen);
int _kcapi_common_accept(struct kcapi_handle *handle);
int _kcapi_common_close(struct kcapi_handle *handle);
ssize_t _kcapi_common_vmsplice_chunk(struct kcapi_handle *handle,
const uint8_t *in, size_t inlen,
uint32_t flags);
int _kcapi_handle_init(struct kcapi_handle **caller, const char *type,
const char *ciphername, uint32_t flags);
void _kcapi_handle_destroy(struct kcapi_handle *handle);
int _kcapi_common_setkey(struct kcapi_handle *handle, const uint8_t *key,
uint32_t keylen);
int _kcapi_common_setentropy(struct kcapi_handle *handle, const uint8_t *ent,
uint32_t entlen);
ssize_t _kcapi_cipher_crypt(struct kcapi_handle *handle, const uint8_t *in,
size_t inlen, uint8_t *out, size_t outlen,
int access, unsigned int enc);
ssize_t _kcapi_cipher_crypt_chunk(struct kcapi_handle *handle,
const uint8_t *in, size_t inlen,
uint8_t *out, size_t outlen,
int access, unsigned int enc);
ssize_t _kcapi_cipher_crypt_aio(struct kcapi_handle *handle,
struct iovec *iniov, struct iovec *outiov,
size_t iovlen, int access, unsigned int enc);
int _kcapi_aio_send_iov(struct kcapi_handle *handle, struct iovec *iov,
size_t iovlen, int access, unsigned int enc);
int _kcapi_aio_read_iov(struct kcapi_handle *handle,
struct iovec *iov, size_t iovlen);
int32_t _kcapi_aio_read_all(struct kcapi_handle *handle, size_t toread,
struct timespec *timeout);
static inline int io_setup(unsigned n, aio_context_t *ctx)
{
return (int)syscall(__NR_io_setup, n, ctx);
}
static inline int io_destroy(aio_context_t ctx)
{
return (int)syscall(__NR_io_destroy, ctx);
}
static inline int io_submit(aio_context_t ctx, long n, struct iocb **iocb)
{
return (int)syscall(__NR_io_submit, ctx, n, iocb);
}
static inline int io_getevents(__attribute__((unused)) aio_context_t ctx,
__attribute__((unused)) long min,
__attribute__((unused)) long max,
__attribute__((unused)) struct io_event *events,
__attribute__((unused)) struct timespec *timeout)
{
#ifdef __NR_io_getevents
return (int)syscall(__NR_io_getevents, ctx, min, max, events, timeout);
#else
return -ENOSYS;
#endif
}
#if HAVE_ATTRIBUTE_SYMVER && __GNUC__ >= 10
# define IMPL_SYMVER(name, version) \
__attribute__((__symver__("kcapi_" #name "@@LIBKCAPI_" version)))
# define ORIG_SYMVER(name, version) \
__attribute__((__symver__("kcapi_" #name "@LIBKCAPI_" version)))
#else
# define IMPL_SYMVER(name, version) \
__asm__(".symver impl_" #name ",kcapi_" #name "@@LIBKCAPI_" version);
# define ORIG_SYMVER(name, version) \
__asm__(".symver orig_" #name ",kcapi_" #name "@LIBKCAPI_" version);
#endif
#ifdef __cplusplus
}
#endif
#endif