~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/tls/tls_main.c

Version: ~ [ linux-5.6-rc7 ] ~ [ linux-5.5.11 ] ~ [ linux-5.4.27 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.112 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.174 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.217 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.217 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.82 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Copyright (c) 2016-2017, Mellanox Technologies. All rights reserved.
  3  * Copyright (c) 2016-2017, Dave Watson <davejwatson@fb.com>. All rights reserved.
  4  *
  5  * This software is available to you under a choice of one of two
  6  * licenses.  You may choose to be licensed under the terms of the GNU
  7  * General Public License (GPL) Version 2, available from the file
  8  * COPYING in the main directory of this source tree, or the
  9  * OpenIB.org BSD license below:
 10  *
 11  *     Redistribution and use in source and binary forms, with or
 12  *     without modification, are permitted provided that the following
 13  *     conditions are met:
 14  *
 15  *      - Redistributions of source code must retain the above
 16  *        copyright notice, this list of conditions and the following
 17  *        disclaimer.
 18  *
 19  *      - Redistributions in binary form must reproduce the above
 20  *        copyright notice, this list of conditions and the following
 21  *        disclaimer in the documentation and/or other materials
 22  *        provided with the distribution.
 23  *
 24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 31  * SOFTWARE.
 32  */
 33 
 34 #include <linux/module.h>
 35 
 36 #include <net/tcp.h>
 37 #include <net/inet_common.h>
 38 #include <linux/highmem.h>
 39 #include <linux/netdevice.h>
 40 #include <linux/sched/signal.h>
 41 #include <linux/inetdevice.h>
 42 
 43 #include <net/tls.h>
 44 
 45 MODULE_AUTHOR("Mellanox Technologies");
 46 MODULE_DESCRIPTION("Transport Layer Security Support");
 47 MODULE_LICENSE("Dual BSD/GPL");
 48 
 49 enum {
 50         TLSV4,
 51         TLSV6,
 52         TLS_NUM_PROTS,
 53 };
 54 
 55 enum {
 56         TLS_BASE,
 57         TLS_SW_TX,
 58         TLS_SW_RX,
 59         TLS_SW_RXTX,
 60         TLS_HW_RECORD,
 61         TLS_NUM_CONFIG,
 62 };
 63 
 64 static struct proto *saved_tcpv6_prot;
 65 static DEFINE_MUTEX(tcpv6_prot_mutex);
 66 static LIST_HEAD(device_list);
 67 static DEFINE_MUTEX(device_mutex);
 68 static struct proto tls_prots[TLS_NUM_PROTS][TLS_NUM_CONFIG];
 69 static struct proto_ops tls_sw_proto_ops;
 70 
 71 static inline void update_sk_prot(struct sock *sk, struct tls_context *ctx)
 72 {
 73         int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4;
 74 
 75         sk->sk_prot = &tls_prots[ip_ver][ctx->conf];
 76 }
 77 
 78 int wait_on_pending_writer(struct sock *sk, long *timeo)
 79 {
 80         int rc = 0;
 81         DEFINE_WAIT_FUNC(wait, woken_wake_function);
 82 
 83         add_wait_queue(sk_sleep(sk), &wait);
 84         while (1) {
 85                 if (!*timeo) {
 86                         rc = -EAGAIN;
 87                         break;
 88                 }
 89 
 90                 if (signal_pending(current)) {
 91                         rc = sock_intr_errno(*timeo);
 92                         break;
 93                 }
 94 
 95                 if (sk_wait_event(sk, timeo, !sk->sk_write_pending, &wait))
 96                         break;
 97         }
 98         remove_wait_queue(sk_sleep(sk), &wait);
 99         return rc;
100 }
101 
102 int tls_push_sg(struct sock *sk,
103                 struct tls_context *ctx,
104                 struct scatterlist *sg,
105                 u16 first_offset,
106                 int flags)
107 {
108         int sendpage_flags = flags | MSG_SENDPAGE_NOTLAST;
109         int ret = 0;
110         struct page *p;
111         size_t size;
112         int offset = first_offset;
113 
114         size = sg->length - offset;
115         offset += sg->offset;
116 
117         ctx->in_tcp_sendpages = true;
118         while (1) {
119                 if (sg_is_last(sg))
120                         sendpage_flags = flags;
121 
122                 /* is sending application-limited? */
123                 tcp_rate_check_app_limited(sk);
124                 p = sg_page(sg);
125 retry:
126                 ret = do_tcp_sendpages(sk, p, offset, size, sendpage_flags);
127 
128                 if (ret != size) {
129                         if (ret > 0) {
130                                 offset += ret;
131                                 size -= ret;
132                                 goto retry;
133                         }
134 
135                         offset -= sg->offset;
136                         ctx->partially_sent_offset = offset;
137                         ctx->partially_sent_record = (void *)sg;
138                         ctx->in_tcp_sendpages = false;
139                         return ret;
140                 }
141 
142                 put_page(p);
143                 sk_mem_uncharge(sk, sg->length);
144                 sg = sg_next(sg);
145                 if (!sg)
146                         break;
147 
148                 offset = sg->offset;
149                 size = sg->length;
150         }
151 
152         clear_bit(TLS_PENDING_CLOSED_RECORD, &ctx->flags);
153         ctx->in_tcp_sendpages = false;
154         ctx->sk_write_space(sk);
155 
156         return 0;
157 }
158 
159 static int tls_handle_open_record(struct sock *sk, int flags)
160 {
161         struct tls_context *ctx = tls_get_ctx(sk);
162 
163         if (tls_is_pending_open_record(ctx))
164                 return ctx->push_pending_record(sk, flags);
165 
166         return 0;
167 }
168 
169 int tls_proccess_cmsg(struct sock *sk, struct msghdr *msg,
170                       unsigned char *record_type)
171 {
172         struct cmsghdr *cmsg;
173         int rc = -EINVAL;
174 
175         for_each_cmsghdr(cmsg, msg) {
176                 if (!CMSG_OK(msg, cmsg))
177                         return -EINVAL;
178                 if (cmsg->cmsg_level != SOL_TLS)
179                         continue;
180 
181                 switch (cmsg->cmsg_type) {
182                 case TLS_SET_RECORD_TYPE:
183                         if (cmsg->cmsg_len < CMSG_LEN(sizeof(*record_type)))
184                                 return -EINVAL;
185 
186                         if (msg->msg_flags & MSG_MORE)
187                                 return -EINVAL;
188 
189                         rc = tls_handle_open_record(sk, msg->msg_flags);
190                         if (rc)
191                                 return rc;
192 
193                         *record_type = *(unsigned char *)CMSG_DATA(cmsg);
194                         rc = 0;
195                         break;
196                 default:
197                         return -EINVAL;
198                 }
199         }
200 
201         return rc;
202 }
203 
204 int tls_push_pending_closed_record(struct sock *sk, struct tls_context *ctx,
205                                    int flags, long *timeo)
206 {
207         struct scatterlist *sg;
208         u16 offset;
209 
210         if (!tls_is_partially_sent_record(ctx))
211                 return ctx->push_pending_record(sk, flags);
212 
213         sg = ctx->partially_sent_record;
214         offset = ctx->partially_sent_offset;
215 
216         ctx->partially_sent_record = NULL;
217         return tls_push_sg(sk, ctx, sg, offset, flags);
218 }
219 
220 static void tls_write_space(struct sock *sk)
221 {
222         struct tls_context *ctx = tls_get_ctx(sk);
223 
224         /* We are already sending pages, ignore notification */
225         if (ctx->in_tcp_sendpages)
226                 return;
227 
228         if (!sk->sk_write_pending && tls_is_pending_closed_record(ctx)) {
229                 gfp_t sk_allocation = sk->sk_allocation;
230                 int rc;
231                 long timeo = 0;
232 
233                 sk->sk_allocation = GFP_ATOMIC;
234                 rc = tls_push_pending_closed_record(sk, ctx,
235                                                     MSG_DONTWAIT |
236                                                     MSG_NOSIGNAL,
237                                                     &timeo);
238                 sk->sk_allocation = sk_allocation;
239 
240                 if (rc < 0)
241                         return;
242         }
243 
244         ctx->sk_write_space(sk);
245 }
246 
247 static void tls_sk_proto_close(struct sock *sk, long timeout)
248 {
249         struct tls_context *ctx = tls_get_ctx(sk);
250         long timeo = sock_sndtimeo(sk, 0);
251         void (*sk_proto_close)(struct sock *sk, long timeout);
252         bool free_ctx = false;
253 
254         lock_sock(sk);
255         sk_proto_close = ctx->sk_proto_close;
256 
257         if (ctx->conf == TLS_BASE || ctx->conf == TLS_HW_RECORD) {
258                 free_ctx = true;
259                 goto skip_tx_cleanup;
260         }
261 
262         if (!tls_complete_pending_work(sk, ctx, 0, &timeo))
263                 tls_handle_open_record(sk, 0);
264 
265         if (ctx->partially_sent_record) {
266                 struct scatterlist *sg = ctx->partially_sent_record;
267 
268                 while (1) {
269                         put_page(sg_page(sg));
270                         sk_mem_uncharge(sk, sg->length);
271 
272                         if (sg_is_last(sg))
273                                 break;
274                         sg++;
275                 }
276         }
277 
278         kfree(ctx->tx.rec_seq);
279         kfree(ctx->tx.iv);
280         kfree(ctx->rx.rec_seq);
281         kfree(ctx->rx.iv);
282 
283         if (ctx->conf == TLS_SW_TX ||
284             ctx->conf == TLS_SW_RX ||
285             ctx->conf == TLS_SW_RXTX) {
286                 tls_sw_free_resources(sk);
287         }
288 
289 skip_tx_cleanup:
290         release_sock(sk);
291         sk_proto_close(sk, timeout);
292         /* free ctx for TLS_HW_RECORD, used by tcp_set_state
293          * for sk->sk_prot->unhash [tls_hw_unhash]
294          */
295         if (free_ctx)
296                 kfree(ctx);
297 }
298 
299 static int do_tls_getsockopt_tx(struct sock *sk, char __user *optval,
300                                 int __user *optlen)
301 {
302         int rc = 0;
303         struct tls_context *ctx = tls_get_ctx(sk);
304         struct tls_crypto_info *crypto_info;
305         int len;
306 
307         if (get_user(len, optlen))
308                 return -EFAULT;
309 
310         if (!optval || (len < sizeof(*crypto_info))) {
311                 rc = -EINVAL;
312                 goto out;
313         }
314 
315         if (!ctx) {
316                 rc = -EBUSY;
317                 goto out;
318         }
319 
320         /* get user crypto info */
321         crypto_info = &ctx->crypto_send;
322 
323         if (!TLS_CRYPTO_INFO_READY(crypto_info)) {
324                 rc = -EBUSY;
325                 goto out;
326         }
327 
328         if (len == sizeof(*crypto_info)) {
329                 if (copy_to_user(optval, crypto_info, sizeof(*crypto_info)))
330                         rc = -EFAULT;
331                 goto out;
332         }
333 
334         switch (crypto_info->cipher_type) {
335         case TLS_CIPHER_AES_GCM_128: {
336                 struct tls12_crypto_info_aes_gcm_128 *
337                   crypto_info_aes_gcm_128 =
338                   container_of(crypto_info,
339                                struct tls12_crypto_info_aes_gcm_128,
340                                info);
341 
342                 if (len != sizeof(*crypto_info_aes_gcm_128)) {
343                         rc = -EINVAL;
344                         goto out;
345                 }
346                 lock_sock(sk);
347                 memcpy(crypto_info_aes_gcm_128->iv,
348                        ctx->tx.iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
349                        TLS_CIPHER_AES_GCM_128_IV_SIZE);
350                 memcpy(crypto_info_aes_gcm_128->rec_seq, ctx->tx.rec_seq,
351                        TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
352                 release_sock(sk);
353                 if (copy_to_user(optval,
354                                  crypto_info_aes_gcm_128,
355                                  sizeof(*crypto_info_aes_gcm_128)))
356                         rc = -EFAULT;
357                 break;
358         }
359         default:
360                 rc = -EINVAL;
361         }
362 
363 out:
364         return rc;
365 }
366 
367 static int do_tls_getsockopt(struct sock *sk, int optname,
368                              char __user *optval, int __user *optlen)
369 {
370         int rc = 0;
371 
372         switch (optname) {
373         case TLS_TX:
374                 rc = do_tls_getsockopt_tx(sk, optval, optlen);
375                 break;
376         default:
377                 rc = -ENOPROTOOPT;
378                 break;
379         }
380         return rc;
381 }
382 
383 static int tls_getsockopt(struct sock *sk, int level, int optname,
384                           char __user *optval, int __user *optlen)
385 {
386         struct tls_context *ctx = tls_get_ctx(sk);
387 
388         if (level != SOL_TLS)
389                 return ctx->getsockopt(sk, level, optname, optval, optlen);
390 
391         return do_tls_getsockopt(sk, optname, optval, optlen);
392 }
393 
394 static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
395                                   unsigned int optlen, int tx)
396 {
397         struct tls_crypto_info *crypto_info;
398         struct tls_context *ctx = tls_get_ctx(sk);
399         int rc = 0;
400         int conf;
401 
402         if (!optval || (optlen < sizeof(*crypto_info))) {
403                 rc = -EINVAL;
404                 goto out;
405         }
406 
407         if (tx)
408                 crypto_info = &ctx->crypto_send;
409         else
410                 crypto_info = &ctx->crypto_recv;
411 
412         /* Currently we don't support set crypto info more than one time */
413         if (TLS_CRYPTO_INFO_READY(crypto_info)) {
414                 rc = -EBUSY;
415                 goto out;
416         }
417 
418         rc = copy_from_user(crypto_info, optval, sizeof(*crypto_info));
419         if (rc) {
420                 rc = -EFAULT;
421                 goto err_crypto_info;
422         }
423 
424         /* check version */
425         if (crypto_info->version != TLS_1_2_VERSION) {
426                 rc = -ENOTSUPP;
427                 goto err_crypto_info;
428         }
429 
430         switch (crypto_info->cipher_type) {
431         case TLS_CIPHER_AES_GCM_128: {
432                 if (optlen != sizeof(struct tls12_crypto_info_aes_gcm_128)) {
433                         rc = -EINVAL;
434                         goto err_crypto_info;
435                 }
436                 rc = copy_from_user(crypto_info + 1, optval + sizeof(*crypto_info),
437                                     optlen - sizeof(*crypto_info));
438                 if (rc) {
439                         rc = -EFAULT;
440                         goto err_crypto_info;
441                 }
442                 break;
443         }
444         default:
445                 rc = -EINVAL;
446                 goto err_crypto_info;
447         }
448 
449         /* currently SW is default, we will have ethtool in future */
450         if (tx) {
451                 rc = tls_set_sw_offload(sk, ctx, 1);
452                 if (ctx->conf == TLS_SW_RX)
453                         conf = TLS_SW_RXTX;
454                 else
455                         conf = TLS_SW_TX;
456         } else {
457                 rc = tls_set_sw_offload(sk, ctx, 0);
458                 if (ctx->conf == TLS_SW_TX)
459                         conf = TLS_SW_RXTX;
460                 else
461                         conf = TLS_SW_RX;
462         }
463 
464         if (rc)
465                 goto err_crypto_info;
466 
467         ctx->conf = conf;
468         update_sk_prot(sk, ctx);
469         if (tx) {
470                 ctx->sk_write_space = sk->sk_write_space;
471                 sk->sk_write_space = tls_write_space;
472         } else {
473                 sk->sk_socket->ops = &tls_sw_proto_ops;
474         }
475         goto out;
476 
477 err_crypto_info:
478         memset(crypto_info, 0, sizeof(*crypto_info));
479 out:
480         return rc;
481 }
482 
483 static int do_tls_setsockopt(struct sock *sk, int optname,
484                              char __user *optval, unsigned int optlen)
485 {
486         int rc = 0;
487 
488         switch (optname) {
489         case TLS_TX:
490         case TLS_RX:
491                 lock_sock(sk);
492                 rc = do_tls_setsockopt_conf(sk, optval, optlen,
493                                             optname == TLS_TX);
494                 release_sock(sk);
495                 break;
496         default:
497                 rc = -ENOPROTOOPT;
498                 break;
499         }
500         return rc;
501 }
502 
503 static int tls_setsockopt(struct sock *sk, int level, int optname,
504                           char __user *optval, unsigned int optlen)
505 {
506         struct tls_context *ctx = tls_get_ctx(sk);
507 
508         if (level != SOL_TLS)
509                 return ctx->setsockopt(sk, level, optname, optval, optlen);
510 
511         return do_tls_setsockopt(sk, optname, optval, optlen);
512 }
513 
514 static struct tls_context *create_ctx(struct sock *sk)
515 {
516         struct inet_connection_sock *icsk = inet_csk(sk);
517         struct tls_context *ctx;
518 
519         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
520         if (!ctx)
521                 return NULL;
522 
523         icsk->icsk_ulp_data = ctx;
524         return ctx;
525 }
526 
527 static int tls_hw_prot(struct sock *sk)
528 {
529         struct tls_context *ctx;
530         struct tls_device *dev;
531         int rc = 0;
532 
533         mutex_lock(&device_mutex);
534         list_for_each_entry(dev, &device_list, dev_list) {
535                 if (dev->feature && dev->feature(dev)) {
536                         ctx = create_ctx(sk);
537                         if (!ctx)
538                                 goto out;
539 
540                         ctx->hash = sk->sk_prot->hash;
541                         ctx->unhash = sk->sk_prot->unhash;
542                         ctx->sk_proto_close = sk->sk_prot->close;
543                         ctx->conf = TLS_HW_RECORD;
544                         update_sk_prot(sk, ctx);
545                         rc = 1;
546                         break;
547                 }
548         }
549 out:
550         mutex_unlock(&device_mutex);
551         return rc;
552 }
553 
554 static void tls_hw_unhash(struct sock *sk)
555 {
556         struct tls_context *ctx = tls_get_ctx(sk);
557         struct tls_device *dev;
558 
559         mutex_lock(&device_mutex);
560         list_for_each_entry(dev, &device_list, dev_list) {
561                 if (dev->unhash)
562                         dev->unhash(dev, sk);
563         }
564         mutex_unlock(&device_mutex);
565         ctx->unhash(sk);
566 }
567 
568 static int tls_hw_hash(struct sock *sk)
569 {
570         struct tls_context *ctx = tls_get_ctx(sk);
571         struct tls_device *dev;
572         int err;
573 
574         err = ctx->hash(sk);
575         mutex_lock(&device_mutex);
576         list_for_each_entry(dev, &device_list, dev_list) {
577                 if (dev->hash)
578                         err |= dev->hash(dev, sk);
579         }
580         mutex_unlock(&device_mutex);
581 
582         if (err)
583                 tls_hw_unhash(sk);
584         return err;
585 }
586 
587 static void build_protos(struct proto *prot, struct proto *base)
588 {
589         prot[TLS_BASE] = *base;
590         prot[TLS_BASE].setsockopt       = tls_setsockopt;
591         prot[TLS_BASE].getsockopt       = tls_getsockopt;
592         prot[TLS_BASE].close            = tls_sk_proto_close;
593 
594         prot[TLS_SW_TX] = prot[TLS_BASE];
595         prot[TLS_SW_TX].sendmsg         = tls_sw_sendmsg;
596         prot[TLS_SW_TX].sendpage        = tls_sw_sendpage;
597 
598         prot[TLS_SW_RX] = prot[TLS_BASE];
599         prot[TLS_SW_RX].recvmsg         = tls_sw_recvmsg;
600         prot[TLS_SW_RX].close           = tls_sk_proto_close;
601 
602         prot[TLS_SW_RXTX] = prot[TLS_SW_TX];
603         prot[TLS_SW_RXTX].recvmsg       = tls_sw_recvmsg;
604         prot[TLS_SW_RXTX].close         = tls_sk_proto_close;
605 
606         prot[TLS_HW_RECORD] = *base;
607         prot[TLS_HW_RECORD].hash        = tls_hw_hash;
608         prot[TLS_HW_RECORD].unhash      = tls_hw_unhash;
609         prot[TLS_HW_RECORD].close       = tls_sk_proto_close;
610 }
611 
612 static int tls_init(struct sock *sk)
613 {
614         int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4;
615         struct tls_context *ctx;
616         int rc = 0;
617 
618         if (tls_hw_prot(sk))
619                 goto out;
620 
621         /* The TLS ulp is currently supported only for TCP sockets
622          * in ESTABLISHED state.
623          * Supporting sockets in LISTEN state will require us
624          * to modify the accept implementation to clone rather then
625          * share the ulp context.
626          */
627         if (sk->sk_state != TCP_ESTABLISHED)
628                 return -ENOTSUPP;
629 
630         /* allocate tls context */
631         ctx = create_ctx(sk);
632         if (!ctx) {
633                 rc = -ENOMEM;
634                 goto out;
635         }
636         ctx->setsockopt = sk->sk_prot->setsockopt;
637         ctx->getsockopt = sk->sk_prot->getsockopt;
638         ctx->sk_proto_close = sk->sk_prot->close;
639 
640         /* Build IPv6 TLS whenever the address of tcpv6_prot changes */
641         if (ip_ver == TLSV6 &&
642             unlikely(sk->sk_prot != smp_load_acquire(&saved_tcpv6_prot))) {
643                 mutex_lock(&tcpv6_prot_mutex);
644                 if (likely(sk->sk_prot != saved_tcpv6_prot)) {
645                         build_protos(tls_prots[TLSV6], sk->sk_prot);
646                         smp_store_release(&saved_tcpv6_prot, sk->sk_prot);
647                 }
648                 mutex_unlock(&tcpv6_prot_mutex);
649         }
650 
651         ctx->conf = TLS_BASE;
652         update_sk_prot(sk, ctx);
653 out:
654         return rc;
655 }
656 
657 void tls_register_device(struct tls_device *device)
658 {
659         mutex_lock(&device_mutex);
660         list_add_tail(&device->dev_list, &device_list);
661         mutex_unlock(&device_mutex);
662 }
663 EXPORT_SYMBOL(tls_register_device);
664 
665 void tls_unregister_device(struct tls_device *device)
666 {
667         mutex_lock(&device_mutex);
668         list_del(&device->dev_list);
669         mutex_unlock(&device_mutex);
670 }
671 EXPORT_SYMBOL(tls_unregister_device);
672 
673 static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mostly = {
674         .name                   = "tls",
675         .uid                    = TCP_ULP_TLS,
676         .user_visible           = true,
677         .owner                  = THIS_MODULE,
678         .init                   = tls_init,
679 };
680 
681 static int __init tls_register(void)
682 {
683         build_protos(tls_prots[TLSV4], &tcp_prot);
684 
685         tls_sw_proto_ops = inet_stream_ops;
686         tls_sw_proto_ops.poll = tls_sw_poll;
687         tls_sw_proto_ops.splice_read = tls_sw_splice_read;
688 
689         tcp_register_ulp(&tcp_tls_ulp_ops);
690 
691         return 0;
692 }
693 
694 static void __exit tls_unregister(void)
695 {
696         tcp_unregister_ulp(&tcp_tls_ulp_ops);
697 }
698 
699 module_init(tls_register);
700 module_exit(tls_unregister);
701 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp