diff options
author | David Howells <dhowells@redhat.com> | 2016-04-07 12:23:51 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-04-11 15:34:41 -0400 |
commit | 648af7fca15901740c7aaafd55904ebd54d01860 (patch) | |
tree | 5aaa5a3d4b192da7bc9bb268d39038c60c068125 | |
parent | 6dd050f88d702e2718bd856ea014487563207756 (diff) |
rxrpc: Absorb the rxkad security module
Absorb the rxkad security module into the af_rxrpc module so that there's
only one module file. This avoids a circular dependency whereby rxkad pins
af_rxrpc and cached connections pin rxkad but can't be manually evicted
(they will expire eventually and cease pinning).
With this change, af_rxrpc can just be unloaded, despite having cached
connections.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/rxrpc/Kconfig | 2 | ||||
-rw-r--r-- | net/rxrpc/Makefile | 3 | ||||
-rw-r--r-- | net/rxrpc/af_rxrpc.c | 9 | ||||
-rw-r--r-- | net/rxrpc/ar-internal.h | 21 | ||||
-rw-r--r-- | net/rxrpc/ar-security.c | 123 | ||||
-rw-r--r-- | net/rxrpc/rxkad.c | 61 |
6 files changed, 85 insertions, 134 deletions
diff --git a/net/rxrpc/Kconfig b/net/rxrpc/Kconfig index 23dcef12b986..784c53163b7b 100644 --- a/net/rxrpc/Kconfig +++ b/net/rxrpc/Kconfig | |||
@@ -30,7 +30,7 @@ config AF_RXRPC_DEBUG | |||
30 | 30 | ||
31 | 31 | ||
32 | config RXKAD | 32 | config RXKAD |
33 | tristate "RxRPC Kerberos security" | 33 | bool "RxRPC Kerberos security" |
34 | depends on AF_RXRPC | 34 | depends on AF_RXRPC |
35 | select CRYPTO | 35 | select CRYPTO |
36 | select CRYPTO_MANAGER | 36 | select CRYPTO_MANAGER |
diff --git a/net/rxrpc/Makefile b/net/rxrpc/Makefile index 5b98c1640d6d..fa09cb55bfce 100644 --- a/net/rxrpc/Makefile +++ b/net/rxrpc/Makefile | |||
@@ -22,8 +22,7 @@ af-rxrpc-y := \ | |||
22 | misc.o | 22 | misc.o |
23 | 23 | ||
24 | af-rxrpc-$(CONFIG_PROC_FS) += ar-proc.o | 24 | af-rxrpc-$(CONFIG_PROC_FS) += ar-proc.o |
25 | af-rxrpc-$(CONFIG_RXKAD) += rxkad.o | ||
25 | af-rxrpc-$(CONFIG_SYSCTL) += sysctl.o | 26 | af-rxrpc-$(CONFIG_SYSCTL) += sysctl.o |
26 | 27 | ||
27 | obj-$(CONFIG_AF_RXRPC) += af-rxrpc.o | 28 | obj-$(CONFIG_AF_RXRPC) += af-rxrpc.o |
28 | |||
29 | obj-$(CONFIG_RXKAD) += rxkad.o | ||
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 9d935fa5a2a9..e45e94ca030f 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c | |||
@@ -806,6 +806,12 @@ static int __init af_rxrpc_init(void) | |||
806 | goto error_work_queue; | 806 | goto error_work_queue; |
807 | } | 807 | } |
808 | 808 | ||
809 | ret = rxrpc_init_security(); | ||
810 | if (ret < 0) { | ||
811 | printk(KERN_CRIT "RxRPC: Cannot initialise security\n"); | ||
812 | goto error_security; | ||
813 | } | ||
814 | |||
809 | ret = proto_register(&rxrpc_proto, 1); | 815 | ret = proto_register(&rxrpc_proto, 1); |
810 | if (ret < 0) { | 816 | if (ret < 0) { |
811 | printk(KERN_CRIT "RxRPC: Cannot register protocol\n"); | 817 | printk(KERN_CRIT "RxRPC: Cannot register protocol\n"); |
@@ -853,6 +859,8 @@ error_sock: | |||
853 | proto_unregister(&rxrpc_proto); | 859 | proto_unregister(&rxrpc_proto); |
854 | error_proto: | 860 | error_proto: |
855 | destroy_workqueue(rxrpc_workqueue); | 861 | destroy_workqueue(rxrpc_workqueue); |
862 | error_security: | ||
863 | rxrpc_exit_security(); | ||
856 | error_work_queue: | 864 | error_work_queue: |
857 | kmem_cache_destroy(rxrpc_call_jar); | 865 | kmem_cache_destroy(rxrpc_call_jar); |
858 | error_call_jar: | 866 | error_call_jar: |
@@ -883,6 +891,7 @@ static void __exit af_rxrpc_exit(void) | |||
883 | remove_proc_entry("rxrpc_conns", init_net.proc_net); | 891 | remove_proc_entry("rxrpc_conns", init_net.proc_net); |
884 | remove_proc_entry("rxrpc_calls", init_net.proc_net); | 892 | remove_proc_entry("rxrpc_calls", init_net.proc_net); |
885 | destroy_workqueue(rxrpc_workqueue); | 893 | destroy_workqueue(rxrpc_workqueue); |
894 | rxrpc_exit_security(); | ||
886 | kmem_cache_destroy(rxrpc_call_jar); | 895 | kmem_cache_destroy(rxrpc_call_jar); |
887 | _leave(""); | 896 | _leave(""); |
888 | } | 897 | } |
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index d38071b09f72..72fd675a891e 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h | |||
@@ -124,11 +124,15 @@ enum rxrpc_command { | |||
124 | * RxRPC security module interface | 124 | * RxRPC security module interface |
125 | */ | 125 | */ |
126 | struct rxrpc_security { | 126 | struct rxrpc_security { |
127 | struct module *owner; /* providing module */ | ||
128 | struct list_head link; /* link in master list */ | ||
129 | const char *name; /* name of this service */ | 127 | const char *name; /* name of this service */ |
130 | u8 security_index; /* security type provided */ | 128 | u8 security_index; /* security type provided */ |
131 | 129 | ||
130 | /* Initialise a security service */ | ||
131 | int (*init)(void); | ||
132 | |||
133 | /* Clean up a security service */ | ||
134 | void (*exit)(void); | ||
135 | |||
132 | /* initialise a connection's security */ | 136 | /* initialise a connection's security */ |
133 | int (*init_connection_security)(struct rxrpc_connection *); | 137 | int (*init_connection_security)(struct rxrpc_connection *); |
134 | 138 | ||
@@ -268,7 +272,7 @@ struct rxrpc_connection { | |||
268 | struct rb_root calls; /* calls on this connection */ | 272 | struct rb_root calls; /* calls on this connection */ |
269 | struct sk_buff_head rx_queue; /* received conn-level packets */ | 273 | struct sk_buff_head rx_queue; /* received conn-level packets */ |
270 | struct rxrpc_call *channels[RXRPC_MAXCALLS]; /* channels (active calls) */ | 274 | struct rxrpc_call *channels[RXRPC_MAXCALLS]; /* channels (active calls) */ |
271 | struct rxrpc_security *security; /* applied security module */ | 275 | const struct rxrpc_security *security; /* applied security module */ |
272 | struct key *key; /* security for this connection (client) */ | 276 | struct key *key; /* security for this connection (client) */ |
273 | struct key *server_key; /* security for this service */ | 277 | struct key *server_key; /* security for this service */ |
274 | struct crypto_skcipher *cipher; /* encryption handle */ | 278 | struct crypto_skcipher *cipher; /* encryption handle */ |
@@ -604,8 +608,8 @@ int rxrpc_recvmsg(struct socket *, struct msghdr *, size_t, int); | |||
604 | /* | 608 | /* |
605 | * ar-security.c | 609 | * ar-security.c |
606 | */ | 610 | */ |
607 | int rxrpc_register_security(struct rxrpc_security *); | 611 | int __init rxrpc_init_security(void); |
608 | void rxrpc_unregister_security(struct rxrpc_security *); | 612 | void rxrpc_exit_security(void); |
609 | int rxrpc_init_client_conn_security(struct rxrpc_connection *); | 613 | int rxrpc_init_client_conn_security(struct rxrpc_connection *); |
610 | int rxrpc_init_server_conn_security(struct rxrpc_connection *); | 614 | int rxrpc_init_server_conn_security(struct rxrpc_connection *); |
611 | int rxrpc_secure_packet(const struct rxrpc_call *, struct sk_buff *, size_t, | 615 | int rxrpc_secure_packet(const struct rxrpc_call *, struct sk_buff *, size_t, |
@@ -646,6 +650,13 @@ extern const s8 rxrpc_ack_priority[]; | |||
646 | extern const char *rxrpc_acks(u8 reason); | 650 | extern const char *rxrpc_acks(u8 reason); |
647 | 651 | ||
648 | /* | 652 | /* |
653 | * rxkad.c | ||
654 | */ | ||
655 | #ifdef CONFIG_RXKAD | ||
656 | extern const struct rxrpc_security rxkad; | ||
657 | #endif | ||
658 | |||
659 | /* | ||
649 | * sysctl.c | 660 | * sysctl.c |
650 | */ | 661 | */ |
651 | #ifdef CONFIG_SYSCTL | 662 | #ifdef CONFIG_SYSCTL |
diff --git a/net/rxrpc/ar-security.c b/net/rxrpc/ar-security.c index ceff6394a65f..6946aec7ab1f 100644 --- a/net/rxrpc/ar-security.c +++ b/net/rxrpc/ar-security.c | |||
@@ -22,109 +22,59 @@ | |||
22 | static LIST_HEAD(rxrpc_security_methods); | 22 | static LIST_HEAD(rxrpc_security_methods); |
23 | static DECLARE_RWSEM(rxrpc_security_sem); | 23 | static DECLARE_RWSEM(rxrpc_security_sem); |
24 | 24 | ||
25 | /* | 25 | static const struct rxrpc_security *rxrpc_security_types[] = { |
26 | * get an RxRPC security module | 26 | #ifdef CONFIG_RXKAD |
27 | */ | 27 | [RXRPC_SECURITY_RXKAD] = &rxkad, |
28 | static struct rxrpc_security *rxrpc_security_get(struct rxrpc_security *sec) | 28 | #endif |
29 | { | 29 | }; |
30 | return try_module_get(sec->owner) ? sec : NULL; | ||
31 | } | ||
32 | 30 | ||
33 | /* | 31 | int __init rxrpc_init_security(void) |
34 | * release an RxRPC security module | ||
35 | */ | ||
36 | static void rxrpc_security_put(struct rxrpc_security *sec) | ||
37 | { | 32 | { |
38 | module_put(sec->owner); | 33 | int i, ret; |
39 | } | ||
40 | 34 | ||
41 | /* | 35 | for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++) { |
42 | * look up an rxrpc security module | 36 | if (rxrpc_security_types[i]) { |
43 | */ | 37 | ret = rxrpc_security_types[i]->init(); |
44 | static struct rxrpc_security *rxrpc_security_lookup(u8 security_index) | 38 | if (ret < 0) |
45 | { | 39 | goto failed; |
46 | struct rxrpc_security *sec = NULL; | ||
47 | |||
48 | _enter(""); | ||
49 | |||
50 | down_read(&rxrpc_security_sem); | ||
51 | |||
52 | list_for_each_entry(sec, &rxrpc_security_methods, link) { | ||
53 | if (sec->security_index == security_index) { | ||
54 | if (unlikely(!rxrpc_security_get(sec))) | ||
55 | break; | ||
56 | goto out; | ||
57 | } | 40 | } |
58 | } | 41 | } |
59 | 42 | ||
60 | sec = NULL; | 43 | return 0; |
61 | out: | 44 | |
62 | up_read(&rxrpc_security_sem); | 45 | failed: |
63 | _leave(" = %p [%s]", sec, sec ? sec->name : ""); | 46 | for (i--; i >= 0; i--) |
64 | return sec; | 47 | if (rxrpc_security_types[i]) |
48 | rxrpc_security_types[i]->exit(); | ||
49 | return ret; | ||
65 | } | 50 | } |
66 | 51 | ||
67 | /** | 52 | void rxrpc_exit_security(void) |
68 | * rxrpc_register_security - register an RxRPC security handler | ||
69 | * @sec: security module | ||
70 | * | ||
71 | * register an RxRPC security handler for use by RxRPC | ||
72 | */ | ||
73 | int rxrpc_register_security(struct rxrpc_security *sec) | ||
74 | { | 53 | { |
75 | struct rxrpc_security *psec; | 54 | int i; |
76 | int ret; | ||
77 | |||
78 | _enter(""); | ||
79 | down_write(&rxrpc_security_sem); | ||
80 | |||
81 | ret = -EEXIST; | ||
82 | list_for_each_entry(psec, &rxrpc_security_methods, link) { | ||
83 | if (psec->security_index == sec->security_index) | ||
84 | goto out; | ||
85 | } | ||
86 | |||
87 | list_add(&sec->link, &rxrpc_security_methods); | ||
88 | |||
89 | printk(KERN_NOTICE "RxRPC: Registered security type %d '%s'\n", | ||
90 | sec->security_index, sec->name); | ||
91 | ret = 0; | ||
92 | 55 | ||
93 | out: | 56 | for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++) |
94 | up_write(&rxrpc_security_sem); | 57 | if (rxrpc_security_types[i]) |
95 | _leave(" = %d", ret); | 58 | rxrpc_security_types[i]->exit(); |
96 | return ret; | ||
97 | } | 59 | } |
98 | 60 | ||
99 | EXPORT_SYMBOL_GPL(rxrpc_register_security); | 61 | /* |
100 | 62 | * look up an rxrpc security module | |
101 | /** | ||
102 | * rxrpc_unregister_security - unregister an RxRPC security handler | ||
103 | * @sec: security module | ||
104 | * | ||
105 | * unregister an RxRPC security handler | ||
106 | */ | 63 | */ |
107 | void rxrpc_unregister_security(struct rxrpc_security *sec) | 64 | static const struct rxrpc_security *rxrpc_security_lookup(u8 security_index) |
108 | { | 65 | { |
109 | 66 | if (security_index >= ARRAY_SIZE(rxrpc_security_types)) | |
110 | _enter(""); | 67 | return NULL; |
111 | down_write(&rxrpc_security_sem); | 68 | return rxrpc_security_types[security_index]; |
112 | list_del_init(&sec->link); | ||
113 | up_write(&rxrpc_security_sem); | ||
114 | |||
115 | printk(KERN_NOTICE "RxRPC: Unregistered security type %d '%s'\n", | ||
116 | sec->security_index, sec->name); | ||
117 | } | 69 | } |
118 | 70 | ||
119 | EXPORT_SYMBOL_GPL(rxrpc_unregister_security); | ||
120 | |||
121 | /* | 71 | /* |
122 | * initialise the security on a client connection | 72 | * initialise the security on a client connection |
123 | */ | 73 | */ |
124 | int rxrpc_init_client_conn_security(struct rxrpc_connection *conn) | 74 | int rxrpc_init_client_conn_security(struct rxrpc_connection *conn) |
125 | { | 75 | { |
76 | const struct rxrpc_security *sec; | ||
126 | struct rxrpc_key_token *token; | 77 | struct rxrpc_key_token *token; |
127 | struct rxrpc_security *sec; | ||
128 | struct key *key = conn->key; | 78 | struct key *key = conn->key; |
129 | int ret; | 79 | int ret; |
130 | 80 | ||
@@ -148,7 +98,6 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn) | |||
148 | 98 | ||
149 | ret = conn->security->init_connection_security(conn); | 99 | ret = conn->security->init_connection_security(conn); |
150 | if (ret < 0) { | 100 | if (ret < 0) { |
151 | rxrpc_security_put(conn->security); | ||
152 | conn->security = NULL; | 101 | conn->security = NULL; |
153 | return ret; | 102 | return ret; |
154 | } | 103 | } |
@@ -162,7 +111,7 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn) | |||
162 | */ | 111 | */ |
163 | int rxrpc_init_server_conn_security(struct rxrpc_connection *conn) | 112 | int rxrpc_init_server_conn_security(struct rxrpc_connection *conn) |
164 | { | 113 | { |
165 | struct rxrpc_security *sec; | 114 | const struct rxrpc_security *sec; |
166 | struct rxrpc_local *local = conn->trans->local; | 115 | struct rxrpc_local *local = conn->trans->local; |
167 | struct rxrpc_sock *rx; | 116 | struct rxrpc_sock *rx; |
168 | struct key *key; | 117 | struct key *key; |
@@ -188,14 +137,12 @@ int rxrpc_init_server_conn_security(struct rxrpc_connection *conn) | |||
188 | 137 | ||
189 | /* the service appears to have died */ | 138 | /* the service appears to have died */ |
190 | read_unlock_bh(&local->services_lock); | 139 | read_unlock_bh(&local->services_lock); |
191 | rxrpc_security_put(sec); | ||
192 | _leave(" = -ENOENT"); | 140 | _leave(" = -ENOENT"); |
193 | return -ENOENT; | 141 | return -ENOENT; |
194 | 142 | ||
195 | found_service: | 143 | found_service: |
196 | if (!rx->securities) { | 144 | if (!rx->securities) { |
197 | read_unlock_bh(&local->services_lock); | 145 | read_unlock_bh(&local->services_lock); |
198 | rxrpc_security_put(sec); | ||
199 | _leave(" = -ENOKEY"); | 146 | _leave(" = -ENOKEY"); |
200 | return -ENOKEY; | 147 | return -ENOKEY; |
201 | } | 148 | } |
@@ -205,7 +152,6 @@ found_service: | |||
205 | &key_type_rxrpc_s, kdesc); | 152 | &key_type_rxrpc_s, kdesc); |
206 | if (IS_ERR(kref)) { | 153 | if (IS_ERR(kref)) { |
207 | read_unlock_bh(&local->services_lock); | 154 | read_unlock_bh(&local->services_lock); |
208 | rxrpc_security_put(sec); | ||
209 | _leave(" = %ld [search]", PTR_ERR(kref)); | 155 | _leave(" = %ld [search]", PTR_ERR(kref)); |
210 | return PTR_ERR(kref); | 156 | return PTR_ERR(kref); |
211 | } | 157 | } |
@@ -253,11 +199,8 @@ void rxrpc_clear_conn_security(struct rxrpc_connection *conn) | |||
253 | { | 199 | { |
254 | _enter("{%d}", conn->debug_id); | 200 | _enter("{%d}", conn->debug_id); |
255 | 201 | ||
256 | if (conn->security) { | 202 | if (conn->security) |
257 | conn->security->clear(conn); | 203 | conn->security->clear(conn); |
258 | rxrpc_security_put(conn->security); | ||
259 | conn->security = NULL; | ||
260 | } | ||
261 | 204 | ||
262 | key_put(conn->key); | 205 | key_put(conn->key); |
263 | key_put(conn->server_key); | 206 | key_put(conn->server_key); |
diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c index f0aeb8163688..6b726a046a7d 100644 --- a/net/rxrpc/rxkad.c +++ b/net/rxrpc/rxkad.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <net/sock.h> | 20 | #include <net/sock.h> |
21 | #include <net/af_rxrpc.h> | 21 | #include <net/af_rxrpc.h> |
22 | #include <keys/rxrpc-type.h> | 22 | #include <keys/rxrpc-type.h> |
23 | #define rxrpc_debug rxkad_debug | ||
24 | #include "ar-internal.h" | 23 | #include "ar-internal.h" |
25 | 24 | ||
26 | #define RXKAD_VERSION 2 | 25 | #define RXKAD_VERSION 2 |
@@ -31,10 +30,6 @@ | |||
31 | #define REALM_SZ 40 /* size of principal's auth domain */ | 30 | #define REALM_SZ 40 /* size of principal's auth domain */ |
32 | #define SNAME_SZ 40 /* size of service name */ | 31 | #define SNAME_SZ 40 /* size of service name */ |
33 | 32 | ||
34 | unsigned int rxrpc_debug; | ||
35 | module_param_named(debug, rxrpc_debug, uint, S_IWUSR | S_IRUGO); | ||
36 | MODULE_PARM_DESC(debug, "rxkad debugging mask"); | ||
37 | |||
38 | struct rxkad_level1_hdr { | 33 | struct rxkad_level1_hdr { |
39 | __be32 data_size; /* true data size (excluding padding) */ | 34 | __be32 data_size; /* true data size (excluding padding) */ |
40 | }; | 35 | }; |
@@ -44,10 +39,6 @@ struct rxkad_level2_hdr { | |||
44 | __be32 checksum; /* decrypted data checksum */ | 39 | __be32 checksum; /* decrypted data checksum */ |
45 | }; | 40 | }; |
46 | 41 | ||
47 | MODULE_DESCRIPTION("RxRPC network protocol type-2 security (Kerberos 4)"); | ||
48 | MODULE_AUTHOR("Red Hat, Inc."); | ||
49 | MODULE_LICENSE("GPL"); | ||
50 | |||
51 | /* | 42 | /* |
52 | * this holds a pinned cipher so that keventd doesn't get called by the cipher | 43 | * this holds a pinned cipher so that keventd doesn't get called by the cipher |
53 | * alloc routine, but since we have it to hand, we use it to decrypt RESPONSE | 44 | * alloc routine, but since we have it to hand, we use it to decrypt RESPONSE |
@@ -1164,12 +1155,35 @@ static void rxkad_clear(struct rxrpc_connection *conn) | |||
1164 | } | 1155 | } |
1165 | 1156 | ||
1166 | /* | 1157 | /* |
1158 | * Initialise the rxkad security service. | ||
1159 | */ | ||
1160 | static int rxkad_init(void) | ||
1161 | { | ||
1162 | /* pin the cipher we need so that the crypto layer doesn't invoke | ||
1163 | * keventd to go get it */ | ||
1164 | rxkad_ci = crypto_alloc_skcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC); | ||
1165 | if (IS_ERR(rxkad_ci)) | ||
1166 | return PTR_ERR(rxkad_ci); | ||
1167 | return 0; | ||
1168 | } | ||
1169 | |||
1170 | /* | ||
1171 | * Clean up the rxkad security service. | ||
1172 | */ | ||
1173 | static void rxkad_exit(void) | ||
1174 | { | ||
1175 | if (rxkad_ci) | ||
1176 | crypto_free_skcipher(rxkad_ci); | ||
1177 | } | ||
1178 | |||
1179 | /* | ||
1167 | * RxRPC Kerberos-based security | 1180 | * RxRPC Kerberos-based security |
1168 | */ | 1181 | */ |
1169 | static struct rxrpc_security rxkad = { | 1182 | const struct rxrpc_security rxkad = { |
1170 | .owner = THIS_MODULE, | ||
1171 | .name = "rxkad", | 1183 | .name = "rxkad", |
1172 | .security_index = RXRPC_SECURITY_RXKAD, | 1184 | .security_index = RXRPC_SECURITY_RXKAD, |
1185 | .init = rxkad_init, | ||
1186 | .exit = rxkad_exit, | ||
1173 | .init_connection_security = rxkad_init_connection_security, | 1187 | .init_connection_security = rxkad_init_connection_security, |
1174 | .prime_packet_security = rxkad_prime_packet_security, | 1188 | .prime_packet_security = rxkad_prime_packet_security, |
1175 | .secure_packet = rxkad_secure_packet, | 1189 | .secure_packet = rxkad_secure_packet, |
@@ -1179,28 +1193,3 @@ static struct rxrpc_security rxkad = { | |||
1179 | .verify_response = rxkad_verify_response, | 1193 | .verify_response = rxkad_verify_response, |
1180 | .clear = rxkad_clear, | 1194 | .clear = rxkad_clear, |
1181 | }; | 1195 | }; |
1182 | |||
1183 | static __init int rxkad_init(void) | ||
1184 | { | ||
1185 | _enter(""); | ||
1186 | |||
1187 | /* pin the cipher we need so that the crypto layer doesn't invoke | ||
1188 | * keventd to go get it */ | ||
1189 | rxkad_ci = crypto_alloc_skcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC); | ||
1190 | if (IS_ERR(rxkad_ci)) | ||
1191 | return PTR_ERR(rxkad_ci); | ||
1192 | |||
1193 | return rxrpc_register_security(&rxkad); | ||
1194 | } | ||
1195 | |||
1196 | module_init(rxkad_init); | ||
1197 | |||
1198 | static __exit void rxkad_exit(void) | ||
1199 | { | ||
1200 | _enter(""); | ||
1201 | |||
1202 | rxrpc_unregister_security(&rxkad); | ||
1203 | crypto_free_skcipher(rxkad_ci); | ||
1204 | } | ||
1205 | |||
1206 | module_exit(rxkad_exit); | ||