• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // SPDX-License-Identifier: GPL-2.0-or-later
2  /*
3   * Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
4   *                    Nicolai Stange <nstange@suse.de>
5   */
6  
7  #include <errno.h>
8  #include <stdio.h>
9  
10  #define TST_NO_DEFAULT_MAIN
11  #include "tst_test.h"
12  #include "tst_crypto.h"
13  #include "tst_netlink.h"
14  
tst_crypto_open(struct tst_crypto_session * ses)15  void tst_crypto_open(struct tst_crypto_session *ses)
16  {
17  	const long ret = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO);
18  
19  	if (ret < 0 && errno == EPROTONOSUPPORT)
20  		tst_brk(TCONF | TERRNO, "NETLINK_CRYPTO is probably disabled");
21  
22  	if (ret < 0) {
23  		tst_brk(TBROK | TERRNO,
24  			"socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CRYPTO)");
25  	}
26  
27  	ses->fd = ret;
28  	ses->seq_num = 0;
29  }
30  
tst_crypto_close(struct tst_crypto_session * ses)31  void tst_crypto_close(struct tst_crypto_session *ses)
32  {
33  	SAFE_CLOSE(ses->fd);
34  }
35  
tst_crypto_recv_ack(struct tst_crypto_session * ses)36  static int tst_crypto_recv_ack(struct tst_crypto_session *ses)
37  {
38  	uint32_t len;
39  	char buf[BUFSIZ];
40  	struct nlmsghdr *nh;
41  
42  	len = SAFE_NETLINK_RECV(ses->fd, buf, sizeof(buf));
43  
44  	for (nh = (struct nlmsghdr *) buf;
45  	     NLMSG_OK(nh, len);
46  	     nh = NLMSG_NEXT(nh, len)) {
47  		if (nh->nlmsg_seq != ses->seq_num) {
48  			tst_brk(TBROK,
49  				"Message out of sequence; type=0%hx, seq_num=%u (not %u)",
50  				nh->nlmsg_type, nh->nlmsg_seq, ses->seq_num);
51  		}
52  
53  		/* Acks use the error message type with error number set to
54  		 * zero. Ofcourse we could also receive an actual error.
55  		 */
56  		if (nh->nlmsg_type == NLMSG_ERROR)
57  			return ((struct nlmsgerr *)NLMSG_DATA(nh))->error;
58  
59  		tst_brk(TBROK, "Unexpected message type; type=0x%hx, seq_num=%u",
60  			nh->nlmsg_type, nh->nlmsg_seq);
61  	}
62  
63  	tst_brk(TBROK, "Empty message from netlink socket?");
64  
65  	return ENODATA;
66  }
67  
tst_crypto_add_alg(struct tst_crypto_session * ses,const struct crypto_user_alg * alg)68  int tst_crypto_add_alg(struct tst_crypto_session *ses,
69  		       const struct crypto_user_alg *alg)
70  {
71  	struct nlmsghdr nh = {
72  		.nlmsg_len = sizeof(struct nlmsghdr) + sizeof(*alg),
73  		.nlmsg_type = CRYPTO_MSG_NEWALG,
74  		.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
75  		.nlmsg_seq = ++(ses->seq_num),
76  		.nlmsg_pid = 0,
77  	};
78  
79  	SAFE_NETLINK_SEND(ses->fd, &nh, alg);
80  
81  	return tst_crypto_recv_ack(ses);
82  }
83  
tst_crypto_del_alg(struct tst_crypto_session * ses,const struct crypto_user_alg * alg)84  int tst_crypto_del_alg(struct tst_crypto_session *ses,
85  		       const struct crypto_user_alg *alg)
86  {
87  	long ret;
88  	unsigned int i = 0;
89  	struct nlmsghdr nh = {
90  		.nlmsg_len = sizeof(struct nlmsghdr) + sizeof(*alg),
91  		.nlmsg_type = CRYPTO_MSG_DELALG,
92  		.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
93  		.nlmsg_pid = 0,
94  	};
95  
96  	while (1) {
97  		nh.nlmsg_seq = ++(ses->seq_num),
98  
99  		SAFE_NETLINK_SEND(ses->fd, &nh, alg);
100  
101  		ret = tst_crypto_recv_ack(ses);
102  		if (ret != -EBUSY || i >= ses->retries)
103  			break;
104  
105  		if (usleep(1) && errno != EINTR)
106  			tst_brk(TBROK | TERRNO, "usleep(1)");
107  
108  		++i;
109  	}
110  
111  	return ret;
112  }
113