blob: 685e0871ebd5b2e7060094ba40234a473e188cd2 [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
* Nicolai Stange <nstange@suse.de>
*/
#include <errno.h>
#include <stdio.h>
#define TST_NO_DEFAULT_MAIN
#include "tst_test.h"
#include "tst_crypto.h"
#include "tst_netlink.h"
void tst_crypto_open(struct tst_crypto_session *ses)
{
TEST(socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO));
if (TST_RET < 0 && TST_ERR == EPROTONOSUPPORT)
tst_brk(TCONF | TTERRNO, "NETLINK_CRYPTO is probably disabled");
if (TST_RET < 0) {
tst_brk(TBROK | TTERRNO,
"socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO)");
}
ses->fd = TST_RET;
ses->seq_num = 0;
}
void tst_crypto_close(struct tst_crypto_session *ses)
{
SAFE_CLOSE(ses->fd);
}
static int tst_crypto_recv_ack(struct tst_crypto_session *ses)
{
uint32_t len;
char buf[BUFSIZ];
struct nlmsghdr *nh;
len = SAFE_NETLINK_RECV(ses->fd, buf, sizeof(buf));
for (nh = (struct nlmsghdr *) buf;
NLMSG_OK(nh, len);
nh = NLMSG_NEXT(nh, len)) {
if (nh->nlmsg_seq != ses->seq_num) {
tst_brk(TBROK,
"Message out of sequence; type=0%hx, seq_num=%u (not %u)",
nh->nlmsg_type, nh->nlmsg_seq, ses->seq_num);
}
/* Acks use the error message type with error number set to
* zero. Ofcourse we could also receive an actual error.
*/
if (nh->nlmsg_type == NLMSG_ERROR)
return ((struct nlmsgerr *)NLMSG_DATA(nh))->error;
tst_brk(TBROK, "Unexpected message type; type=0x%hx, seq_num=%u",
nh->nlmsg_type, nh->nlmsg_seq);
}
tst_brk(TBROK, "Empty message from netlink socket?");
return ENODATA;
}
int tst_crypto_add_alg(struct tst_crypto_session *ses,
const struct crypto_user_alg *alg)
{
struct nlmsghdr nh = {
.nlmsg_len = sizeof(struct nlmsghdr) + sizeof(*alg),
.nlmsg_type = CRYPTO_MSG_NEWALG,
.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
.nlmsg_seq = ++(ses->seq_num),
.nlmsg_pid = 0,
};
SAFE_NETLINK_SEND(ses->fd, &nh, alg);
return tst_crypto_recv_ack(ses);
}
int tst_crypto_del_alg(struct tst_crypto_session *ses,
const struct crypto_user_alg *alg)
{
unsigned int i = 0;
struct nlmsghdr nh = {
.nlmsg_len = sizeof(struct nlmsghdr) + sizeof(*alg),
.nlmsg_type = CRYPTO_MSG_DELALG,
.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
.nlmsg_pid = 0,
};
while (1) {
nh.nlmsg_seq = ++(ses->seq_num),
SAFE_NETLINK_SEND(ses->fd, &nh, alg);
TEST(tst_crypto_recv_ack(ses));
if (TST_RET != -EBUSY || i >= ses->retries)
break;
if (usleep(1) && errno != EINTR)
tst_brk(TBROK | TERRNO, "usleep(1)");
++i;
}
return TST_RET;
}