You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
2.5 KiB
111 lines
2.5 KiB
// 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;
|
|
}
|