Whamcloud - gitweb
3f703372d272f5939a659f83bcb75337fdf9a5d1
[fs/lustre-release.git] / lustre / ptlrpc / gss / gss_bulk.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2015, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  *
32  * lustre/ptlrpc/gss/gss_bulk.c
33  *
34  * Author: Eric Mei <eric.mei@sun.com>
35  */
36
37 #define DEBUG_SUBSYSTEM S_SEC
38 #include <linux/init.h>
39 #include <linux/module.h>
40 #include <linux/slab.h>
41 #include <linux/dcache.h>
42 #include <linux/fs.h>
43 #include <linux/mutex.h>
44 #include <linux/crypto.h>
45
46 #include <obd.h>
47 #include <obd_class.h>
48 #include <obd_support.h>
49 #include <lustre/lustre_idl.h>
50 #include <lustre_net.h>
51 #include <lustre_import.h>
52 #include <lustre_sec.h>
53
54 #include "gss_err.h"
55 #include "gss_internal.h"
56 #include "gss_api.h"
57
58 int gss_cli_ctx_wrap_bulk(struct ptlrpc_cli_ctx *ctx,
59                           struct ptlrpc_request *req,
60                           struct ptlrpc_bulk_desc *desc)
61 {
62         struct gss_cli_ctx              *gctx;
63         struct lustre_msg               *msg;
64         struct ptlrpc_bulk_sec_desc     *bsd;
65         rawobj_t                         token;
66         __u32                            maj;
67         int                              offset;
68         int                              rc;
69         ENTRY;
70
71         LASSERT(req->rq_pack_bulk);
72         LASSERT(req->rq_bulk_read || req->rq_bulk_write);
73         LASSERT(ptlrpc_is_bulk_desc_kiov(desc->bd_type));
74
75         gctx = container_of(ctx, struct gss_cli_ctx, gc_base);
76         LASSERT(gctx->gc_mechctx);
77
78         switch (SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc)) {
79         case SPTLRPC_SVC_NULL:
80                 LASSERT(req->rq_reqbuf->lm_bufcount >= 3);
81                 msg = req->rq_reqbuf;
82                 offset = msg->lm_bufcount - 1;
83                 break;
84         case SPTLRPC_SVC_AUTH:
85         case SPTLRPC_SVC_INTG:
86                 LASSERT(req->rq_reqbuf->lm_bufcount >= 4);
87                 msg = req->rq_reqbuf;
88                 offset = msg->lm_bufcount - 2;
89                 break;
90         case SPTLRPC_SVC_PRIV:
91                 LASSERT(req->rq_clrbuf->lm_bufcount >= 2);
92                 msg = req->rq_clrbuf;
93                 offset = msg->lm_bufcount - 1;
94                 break;
95         default:
96                 LBUG();
97         }
98
99         bsd = lustre_msg_buf(msg, offset, sizeof(*bsd));
100         bsd->bsd_version = 0;
101         bsd->bsd_flags = 0;
102         bsd->bsd_type = SPTLRPC_BULK_DEFAULT;
103         bsd->bsd_svc = SPTLRPC_FLVR_BULK_SVC(req->rq_flvr.sf_rpc);
104
105         if (bsd->bsd_svc == SPTLRPC_BULK_SVC_NULL)
106                 RETURN(0);
107
108         LASSERT(bsd->bsd_svc == SPTLRPC_BULK_SVC_INTG ||
109                 bsd->bsd_svc == SPTLRPC_BULK_SVC_PRIV);
110
111         if (req->rq_bulk_read) {
112                 /*
113                  * bulk read: prepare receiving pages only for privacy mode.
114                  */
115                 if (bsd->bsd_svc == SPTLRPC_BULK_SVC_PRIV)
116                         return gss_cli_prep_bulk(req, desc);
117         } else {
118                 /*
119                  * bulk write: sign or encrypt bulk pages.
120                  */
121                 bsd->bsd_nob = desc->bd_nob;
122
123                 if (bsd->bsd_svc == SPTLRPC_BULK_SVC_INTG) {
124                         /* integrity mode */
125                         token.data = bsd->bsd_data;
126                         token.len = lustre_msg_buflen(msg, offset) -
127                                     sizeof(*bsd);
128
129                         maj = lgss_get_mic(gctx->gc_mechctx, 0, NULL,
130                                            desc->bd_iov_count,
131                                            GET_KIOV(desc),
132                                            &token);
133                         if (maj != GSS_S_COMPLETE) {
134                                 CWARN("failed to sign bulk data: %x\n", maj);
135                                 RETURN(-EACCES);
136                         }
137                 } else {
138                         /* privacy mode */
139                         if (desc->bd_iov_count == 0)
140                                 RETURN(0);
141
142                         rc = sptlrpc_enc_pool_get_pages(desc);
143                         if (rc) {
144                                 CERROR("bulk write: failed to allocate "
145                                        "encryption pages: %d\n", rc);
146                                 RETURN(rc);
147                         }
148
149                         token.data = bsd->bsd_data;
150                         token.len = lustre_msg_buflen(msg, offset) -
151                                     sizeof(*bsd);
152
153                         maj = lgss_wrap_bulk(gctx->gc_mechctx, desc, &token, 0);
154                         if (maj != GSS_S_COMPLETE) {
155                                 CWARN("fail to encrypt bulk data: %x\n", maj);
156                                 RETURN(-EACCES);
157                         }
158                 }
159         }
160
161         RETURN(0);
162 }
163
164 int gss_cli_ctx_unwrap_bulk(struct ptlrpc_cli_ctx *ctx,
165                             struct ptlrpc_request *req,
166                             struct ptlrpc_bulk_desc *desc)
167 {
168         struct gss_cli_ctx              *gctx;
169         struct lustre_msg               *rmsg, *vmsg;
170         struct ptlrpc_bulk_sec_desc     *bsdr, *bsdv;
171         rawobj_t                         token;
172         __u32                            maj;
173         int                              roff, voff;
174         ENTRY;
175
176         LASSERT(req->rq_pack_bulk);
177         LASSERT(req->rq_bulk_read || req->rq_bulk_write);
178         LASSERT(ptlrpc_is_bulk_desc_kiov(desc->bd_type));
179
180         switch (SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc)) {
181         case SPTLRPC_SVC_NULL:
182                 vmsg = req->rq_repdata;
183                 LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 3);
184                 voff = vmsg->lm_bufcount - 1;
185
186                 rmsg = req->rq_reqbuf;
187                 LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 3);
188                 roff = rmsg->lm_bufcount - 1; /* last segment */
189                 break;
190         case SPTLRPC_SVC_AUTH:
191         case SPTLRPC_SVC_INTG:
192                 vmsg = req->rq_repdata;
193                 LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 4);
194                 voff = vmsg->lm_bufcount - 2;
195
196                 rmsg = req->rq_reqbuf;
197                 LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 4);
198                 roff = rmsg->lm_bufcount - 2; /* second last segment */
199                 break;
200         case SPTLRPC_SVC_PRIV:
201                 vmsg = req->rq_repdata;
202                 LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 2);
203                 voff = vmsg->lm_bufcount - 1;
204
205                 rmsg = req->rq_clrbuf;
206                 LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 2);
207                 roff = rmsg->lm_bufcount - 1; /* last segment */
208                 break;
209         default:
210                 LBUG();
211         }
212
213         bsdr = lustre_msg_buf(rmsg, roff, sizeof(*bsdr));
214         bsdv = lustre_msg_buf(vmsg, voff, sizeof(*bsdv));
215         LASSERT(bsdr && bsdv);
216
217         if (bsdr->bsd_version != bsdv->bsd_version ||
218             bsdr->bsd_type != bsdv->bsd_type ||
219             bsdr->bsd_svc != bsdv->bsd_svc) {
220                 CERROR("bulk security descriptor mismatch: "
221                        "(%u,%u,%u) != (%u,%u,%u)\n",
222                        bsdr->bsd_version, bsdr->bsd_type, bsdr->bsd_svc,
223                        bsdv->bsd_version, bsdv->bsd_type, bsdv->bsd_svc);
224                 RETURN(-EPROTO);
225         }
226
227         LASSERT(bsdv->bsd_svc == SPTLRPC_BULK_SVC_NULL ||
228                 bsdv->bsd_svc == SPTLRPC_BULK_SVC_INTG ||
229                 bsdv->bsd_svc == SPTLRPC_BULK_SVC_PRIV);
230
231         /*
232          * in privacy mode if return success, make sure bd_nob_transferred
233          * is the actual size of the clear text, otherwise upper layer
234          * may be surprised.
235          */
236         if (req->rq_bulk_write) {
237                 if (bsdv->bsd_flags & BSD_FL_ERR) {
238                         CERROR("server reported bulk i/o failure\n");
239                         RETURN(-EIO);
240                 }
241
242                 if (bsdv->bsd_svc == SPTLRPC_BULK_SVC_PRIV)
243                         desc->bd_nob_transferred = desc->bd_nob;
244         } else {
245                 /*
246                  * bulk read, upon return success, bd_nob_transferred is
247                  * the size of plain text actually received.
248                  */
249                 gctx = container_of(ctx, struct gss_cli_ctx, gc_base);
250                 LASSERT(gctx->gc_mechctx);
251
252                 if (bsdv->bsd_svc == SPTLRPC_BULK_SVC_INTG) {
253                         int i, nob;
254
255                         /* fix the actual data size */
256                         for (i = 0, nob = 0; i < desc->bd_iov_count; i++) {
257                                 if (BD_GET_KIOV(desc, i).kiov_len + nob >
258                                     desc->bd_nob_transferred) {
259                                         BD_GET_KIOV(desc, i).kiov_len =
260                                                 desc->bd_nob_transferred - nob;
261                                 }
262                                 nob += BD_GET_KIOV(desc, i).kiov_len;
263                         }
264
265                         token.data = bsdv->bsd_data;
266                         token.len = lustre_msg_buflen(vmsg, voff) -
267                                     sizeof(*bsdv);
268
269                         maj = lgss_verify_mic(gctx->gc_mechctx, 0, NULL,
270                                               desc->bd_iov_count,
271                                               GET_KIOV(desc),
272                                               &token);
273                         if (maj != GSS_S_COMPLETE) {
274                                 CERROR("failed to verify bulk read: %x\n", maj);
275                                 RETURN(-EACCES);
276                         }
277                 } else if (bsdv->bsd_svc == SPTLRPC_BULK_SVC_PRIV) {
278                         desc->bd_nob = bsdv->bsd_nob;
279                         if (desc->bd_nob == 0)
280                                 RETURN(0);
281
282                         token.data = bsdv->bsd_data;
283                         token.len = lustre_msg_buflen(vmsg, voff) -
284                                     sizeof(*bsdr);
285
286                         maj = lgss_unwrap_bulk(gctx->gc_mechctx, desc,
287                                                &token, 1);
288                         if (maj != GSS_S_COMPLETE) {
289                                 CERROR("failed to decrypt bulk read: %x\n",
290                                        maj);
291                                 RETURN(-EACCES);
292                         }
293
294                         desc->bd_nob_transferred = desc->bd_nob;
295                 }
296         }
297
298         RETURN(0);
299 }
300
301 static int gss_prep_bulk(struct ptlrpc_bulk_desc *desc,
302                          struct gss_ctx *mechctx)
303 {
304         int     rc;
305
306         if (desc->bd_iov_count == 0)
307                 return 0;
308
309         rc = sptlrpc_enc_pool_get_pages(desc);
310         if (rc)
311                 return rc;
312
313         if (lgss_prep_bulk(mechctx, desc) != GSS_S_COMPLETE)
314                 return -EACCES;
315
316         return 0;
317 }
318
319 int gss_cli_prep_bulk(struct ptlrpc_request *req,
320                       struct ptlrpc_bulk_desc *desc)
321 {
322         int             rc;
323         ENTRY;
324
325         LASSERT(req->rq_cli_ctx);
326         LASSERT(req->rq_pack_bulk);
327         LASSERT(req->rq_bulk_read);
328
329         if (SPTLRPC_FLVR_BULK_SVC(req->rq_flvr.sf_rpc) != SPTLRPC_BULK_SVC_PRIV)
330                 RETURN(0);
331
332         rc = gss_prep_bulk(desc, ctx2gctx(req->rq_cli_ctx)->gc_mechctx);
333         if (rc)
334                 CERROR("bulk read: failed to prepare encryption "
335                        "pages: %d\n", rc);
336
337         RETURN(rc);
338 }
339
340 int gss_svc_prep_bulk(struct ptlrpc_request *req,
341                       struct ptlrpc_bulk_desc *desc)
342 {
343         struct gss_svc_reqctx        *grctx;
344         struct ptlrpc_bulk_sec_desc  *bsd;
345         int                           rc;
346         ENTRY;
347
348         LASSERT(req->rq_svc_ctx);
349         LASSERT(req->rq_pack_bulk);
350         LASSERT(req->rq_bulk_write);
351
352         grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
353         LASSERT(grctx->src_reqbsd);
354         LASSERT(grctx->src_repbsd);
355         LASSERT(grctx->src_ctx);
356         LASSERT(grctx->src_ctx->gsc_mechctx);
357
358         bsd = grctx->src_reqbsd;
359         if (bsd->bsd_svc != SPTLRPC_BULK_SVC_PRIV)
360                 RETURN(0);
361
362         rc = gss_prep_bulk(desc, grctx->src_ctx->gsc_mechctx);
363         if (rc)
364                 CERROR("bulk write: failed to prepare encryption "
365                        "pages: %d\n", rc);
366
367         RETURN(rc);
368 }
369
370 int gss_svc_unwrap_bulk(struct ptlrpc_request *req,
371                         struct ptlrpc_bulk_desc *desc)
372 {
373         struct gss_svc_reqctx        *grctx;
374         struct ptlrpc_bulk_sec_desc  *bsdr, *bsdv;
375         rawobj_t                      token;
376         __u32                         maj;
377         ENTRY;
378
379         LASSERT(req->rq_svc_ctx);
380         LASSERT(req->rq_pack_bulk);
381         LASSERT(req->rq_bulk_write);
382         LASSERT(ptlrpc_is_bulk_desc_kiov(desc->bd_type));
383
384         grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
385
386         LASSERT(grctx->src_reqbsd);
387         LASSERT(grctx->src_repbsd);
388         LASSERT(grctx->src_ctx);
389         LASSERT(grctx->src_ctx->gsc_mechctx);
390
391         bsdr = grctx->src_reqbsd;
392         bsdv = grctx->src_repbsd;
393
394         /* bsdr has been sanity checked during unpacking */
395         bsdv->bsd_version = 0;
396         bsdv->bsd_type = SPTLRPC_BULK_DEFAULT;
397         bsdv->bsd_svc = bsdr->bsd_svc;
398         bsdv->bsd_flags = 0;
399
400         switch (bsdv->bsd_svc) {
401         case SPTLRPC_BULK_SVC_INTG:
402                 token.data = bsdr->bsd_data;
403                 token.len = grctx->src_reqbsd_size - sizeof(*bsdr);
404
405                 maj = lgss_verify_mic(grctx->src_ctx->gsc_mechctx, 0, NULL,
406                                       desc->bd_iov_count,
407                                       GET_KIOV(desc), &token);
408                 if (maj != GSS_S_COMPLETE) {
409                         bsdv->bsd_flags |= BSD_FL_ERR;
410                         CERROR("failed to verify bulk signature: %x\n", maj);
411                         RETURN(-EACCES);
412                 }
413                 break;
414         case SPTLRPC_BULK_SVC_PRIV:
415                 if (bsdr->bsd_nob != desc->bd_nob) {
416                         bsdv->bsd_flags |= BSD_FL_ERR;
417                         CERROR("prepared nob %d doesn't match the actual "
418                                "nob %d\n", desc->bd_nob, bsdr->bsd_nob);
419                         RETURN(-EPROTO);
420                 }
421
422                 if (desc->bd_iov_count == 0) {
423                         LASSERT(desc->bd_nob == 0);
424                         break;
425                 }
426
427                 token.data = bsdr->bsd_data;
428                 token.len = grctx->src_reqbsd_size - sizeof(*bsdr);
429
430                 maj = lgss_unwrap_bulk(grctx->src_ctx->gsc_mechctx,
431                                        desc, &token, 0);
432                 if (maj != GSS_S_COMPLETE) {
433                         bsdv->bsd_flags |= BSD_FL_ERR;
434                         CERROR("failed decrypt bulk data: %x\n", maj);
435                         RETURN(-EACCES);
436                 }
437
438                 /* mimic gss_cli_ctx_unwrap_bulk */
439                 desc->bd_nob_transferred = desc->bd_nob;
440
441                 break;
442         }
443
444         RETURN(0);
445 }
446
447 int gss_svc_wrap_bulk(struct ptlrpc_request *req,
448                       struct ptlrpc_bulk_desc *desc)
449 {
450         struct gss_svc_reqctx        *grctx;
451         struct ptlrpc_bulk_sec_desc  *bsdr, *bsdv;
452         rawobj_t                      token;
453         __u32                         maj;
454         int                           rc;
455         ENTRY;
456
457         LASSERT(req->rq_svc_ctx);
458         LASSERT(req->rq_pack_bulk);
459         LASSERT(req->rq_bulk_read);
460         LASSERT(ptlrpc_is_bulk_desc_kiov(desc->bd_type));
461
462         grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
463
464         LASSERT(grctx->src_reqbsd);
465         LASSERT(grctx->src_repbsd);
466         LASSERT(grctx->src_ctx);
467         LASSERT(grctx->src_ctx->gsc_mechctx);
468
469         bsdr = grctx->src_reqbsd;
470         bsdv = grctx->src_repbsd;
471
472         /* bsdr has been sanity checked during unpacking */
473         bsdv->bsd_version = 0;
474         bsdv->bsd_type = SPTLRPC_BULK_DEFAULT;
475         bsdv->bsd_svc = bsdr->bsd_svc;
476         bsdv->bsd_flags = 0;
477
478         switch (bsdv->bsd_svc) {
479         case SPTLRPC_BULK_SVC_INTG:
480                 token.data = bsdv->bsd_data;
481                 token.len = grctx->src_repbsd_size - sizeof(*bsdv);
482
483                 maj = lgss_get_mic(grctx->src_ctx->gsc_mechctx, 0, NULL,
484                                    desc->bd_iov_count,
485                                    GET_KIOV(desc), &token);
486                 if (maj != GSS_S_COMPLETE) {
487                         bsdv->bsd_flags |= BSD_FL_ERR;
488                         CERROR("failed to sign bulk data: %x\n", maj);
489                         RETURN(-EACCES);
490                 }
491                 break;
492         case SPTLRPC_BULK_SVC_PRIV:
493                 bsdv->bsd_nob = desc->bd_nob;
494
495                 if (desc->bd_iov_count == 0) {
496                         LASSERT(desc->bd_nob == 0);
497                         break;
498                 }
499
500                 rc = sptlrpc_enc_pool_get_pages(desc);
501                 if (rc) {
502                         bsdv->bsd_flags |= BSD_FL_ERR;
503                         CERROR("bulk read: failed to allocate encryption "
504                                "pages: %d\n", rc);
505                         RETURN(rc);
506                 }
507
508                 token.data = bsdv->bsd_data;
509                 token.len = grctx->src_repbsd_size - sizeof(*bsdv);
510
511                 maj = lgss_wrap_bulk(grctx->src_ctx->gsc_mechctx,
512                                      desc, &token, 1);
513                 if (maj != GSS_S_COMPLETE) {
514                         bsdv->bsd_flags |= BSD_FL_ERR;
515                         CERROR("failed to encrypt bulk data: %x\n", maj);
516                         RETURN(-EACCES);
517                 }
518                 break;
519         }
520
521         RETURN(0);
522 }