Whamcloud - gitweb
land b_colibri_devel on HEAD:
[fs/lustre-release.git] / lustre / ptlrpc / gss / gss_bulk.c
index cede791..9f829ad 100644 (file)
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  * Copyright (C) 2006 Cluster File Systems, Inc.
+ *   Author: Eric Mei <ericm@clusterfs.com>
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -56,6 +57,7 @@ int do_bulk_privacy(struct gss_ctx *gctx,
 {
         struct crypto_tfm  *tfm;
         struct scatterlist  sg, sg2, *sgd;
+        unsigned int        blksize;
         int                 i, rc;
         __u8                local_iv[sizeof(bsd->bsd_iv)];
 
@@ -67,12 +69,6 @@ int do_bulk_privacy(struct gss_ctx *gctx,
         if (alg == BULK_PRIV_ALG_NULL)
                 return 0;
 
-        if (encrypt)
-                get_random_bytes(bsd->bsd_iv, sizeof(bsd->bsd_iv));
-
-        /* compute the secret iv */
-        lgss_plain_encrypt(gctx, sizeof(local_iv), bsd->bsd_iv, local_iv);
-
         tfm = crypto_alloc_tfm(sptlrpc_bulk_priv_alg2name(alg),
                                sptlrpc_bulk_priv_alg2flags(alg));
         if (tfm == NULL) {
@@ -81,12 +77,25 @@ int do_bulk_privacy(struct gss_ctx *gctx,
                 return -ENOMEM;
         }
 
+        blksize = crypto_tfm_alg_blocksize(tfm);
+        LASSERT(blksize <= sizeof(local_iv));
+
+        if (encrypt)
+                get_random_bytes(bsd->bsd_iv, sizeof(bsd->bsd_iv));
+
+        /* compute the secret iv */
+        rc = lgss_plain_encrypt(gctx, 0,
+                                sizeof(local_iv), bsd->bsd_iv, local_iv);
+        if (rc) {
+                CERROR("failed to compute secret iv: %d\n", rc);
+                goto out;
+        }
+
         rc = crypto_cipher_setkey(tfm, local_iv, sizeof(local_iv));
         if (rc) {
                 CERROR("Failed to set key for TFM %s: %d\n",
                        sptlrpc_bulk_priv_alg2name(alg), rc);
-                crypto_free_tfm(tfm);
-                return rc;
+                goto out;
         }
 
         for (i = 0; i < desc->bd_iov_count; i++) {
@@ -118,12 +127,12 @@ int do_bulk_privacy(struct gss_ctx *gctx,
                  */
         }
 
-        crypto_free_tfm(tfm);
-
         if (encrypt)
                 bsd->bsd_priv_alg = alg;
 
-        return 0;
+out:
+        crypto_free_tfm(tfm);
+        return rc;
 }
 
 int gss_cli_ctx_wrap_bulk(struct ptlrpc_cli_ctx *ctx,
@@ -133,15 +142,20 @@ int gss_cli_ctx_wrap_bulk(struct ptlrpc_cli_ctx *ctx,
         struct gss_cli_ctx              *gctx;
         struct lustre_msg               *msg;
         struct ptlrpc_bulk_sec_desc     *bsdr;
-        struct sec_flavor_config        *conf;
         int                              offset, rc;
         ENTRY;
 
-        LASSERT(SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor));
+        LASSERT(req->rq_pack_bulk);
         LASSERT(req->rq_bulk_read || req->rq_bulk_write);
 
-        switch (SEC_FLAVOR_SVC(req->rq_sec_flavor)) {
+        switch (RPC_FLVR_SVC(req->rq_flvr.sf_rpc)) {
+        case SPTLRPC_SVC_NULL:
+                LASSERT(req->rq_reqbuf->lm_bufcount >= 3);
+                msg = req->rq_reqbuf;
+                offset = msg->lm_bufcount - 1;
+                break;
         case SPTLRPC_SVC_AUTH:
+        case SPTLRPC_SVC_INTG:
                 LASSERT(req->rq_reqbuf->lm_bufcount >= 4);
                 msg = req->rq_reqbuf;
                 offset = msg->lm_bufcount - 2;
@@ -156,23 +170,22 @@ int gss_cli_ctx_wrap_bulk(struct ptlrpc_cli_ctx *ctx,
         }
 
         /* make checksum */
-        conf = &req->rq_import->imp_obd->u.cli.cl_sec_conf;
-        rc = bulk_csum_cli_request(desc, req->rq_bulk_read, conf->sfc_bulk_csum,
-                                   msg, offset);
+        rc = bulk_csum_cli_request(desc, req->rq_bulk_read,
+                                   req->rq_flvr.sf_bulk_csum, msg, offset);
         if (rc) {
                 CERROR("client bulk %s: failed to generate checksum: %d\n",
                        req->rq_bulk_read ? "read" : "write", rc);
                 RETURN(rc);
         }
 
-        if (conf->sfc_bulk_priv == BULK_PRIV_ALG_NULL)
+        if (req->rq_flvr.sf_bulk_priv == BULK_PRIV_ALG_NULL)
                 RETURN(0);
 
         /* previous bulk_csum_cli_request() has verified bsdr is good */
         bsdr = lustre_msg_buf(msg, offset, 0);
 
         if (req->rq_bulk_read) {
-                bsdr->bsd_priv_alg = conf->sfc_bulk_priv;
+                bsdr->bsd_priv_alg = req->rq_flvr.sf_bulk_priv;
                 RETURN(0);
         }
 
@@ -187,7 +200,7 @@ int gss_cli_ctx_wrap_bulk(struct ptlrpc_cli_ctx *ctx,
         LASSERT(gctx->gc_mechctx);
 
         rc = do_bulk_privacy(gctx->gc_mechctx, desc, 1,
-                             conf->sfc_bulk_priv, bsdr);
+                             req->rq_flvr.sf_bulk_priv, bsdr);
         if (rc)
                 CERROR("bulk write: client failed to encrypt pages\n");
 
@@ -204,11 +217,21 @@ int gss_cli_ctx_unwrap_bulk(struct ptlrpc_cli_ctx *ctx,
         int                              roff, voff, rc;
         ENTRY;
 
-        LASSERT(SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor));
+        LASSERT(req->rq_pack_bulk);
         LASSERT(req->rq_bulk_read || req->rq_bulk_write);
 
-        switch (SEC_FLAVOR_SVC(req->rq_sec_flavor)) {
+        switch (RPC_FLVR_SVC(req->rq_flvr.sf_rpc)) {
+        case SPTLRPC_SVC_NULL:
+                vmsg = req->rq_repbuf;
+                voff = vmsg->lm_bufcount - 1;
+                LASSERT(vmsg && vmsg->lm_bufcount >= 3);
+
+                rmsg = req->rq_reqbuf;
+                roff = rmsg->lm_bufcount - 1; /* last segment */
+                LASSERT(rmsg && rmsg->lm_bufcount >= 3);
+                break;
         case SPTLRPC_SVC_AUTH:
+        case SPTLRPC_SVC_INTG:
                 vmsg = req->rq_repbuf;
                 voff = vmsg->lm_bufcount - 2;
                 LASSERT(vmsg && vmsg->lm_bufcount >= 4);
@@ -264,43 +287,36 @@ verify_csum:
 int gss_svc_unwrap_bulk(struct ptlrpc_request *req,
                         struct ptlrpc_bulk_desc *desc)
 {
-        struct ptlrpc_reply_state    *rs = req->rq_reply_state;
         struct gss_svc_reqctx        *grctx;
-        struct ptlrpc_bulk_sec_desc  *bsdv;
-        int                           voff, roff, rc;
+        int                           rc;
         ENTRY;
 
-        LASSERT(rs);
+        LASSERT(req->rq_svc_ctx);
+        LASSERT(req->rq_pack_bulk);
         LASSERT(req->rq_bulk_write);
 
-        if (SEC_FLAVOR_SVC(req->rq_sec_flavor) == SPTLRPC_SVC_PRIV) {
-                LASSERT(req->rq_reqbuf->lm_bufcount >= 2);
-                LASSERT(rs->rs_repbuf->lm_bufcount >= 2);
-                voff = req->rq_reqbuf->lm_bufcount - 1;
-                roff = rs->rs_repbuf->lm_bufcount - 1;
-        } else {
-                LASSERT(req->rq_reqbuf->lm_bufcount >= 4);
-                LASSERT(rs->rs_repbuf->lm_bufcount >= 4);
-                voff = req->rq_reqbuf->lm_bufcount - 2;
-                roff = rs->rs_repbuf->lm_bufcount - 2;
-        }
+        grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
 
-        bsdv = lustre_msg_buf(req->rq_reqbuf, voff, sizeof(*bsdv));
-        if (bsdv->bsd_priv_alg != BULK_PRIV_ALG_NULL) {
-                grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
-                LASSERT(grctx->src_ctx);
-                LASSERT(grctx->src_ctx->gsc_mechctx);
+        LASSERT(grctx->src_reqbsd);
+        LASSERT(grctx->src_repbsd);
+        LASSERT(grctx->src_ctx);
+        LASSERT(grctx->src_ctx->gsc_mechctx);
 
+        /* decrypt bulk data if it's encrypted */
+        if (grctx->src_reqbsd->bsd_priv_alg != BULK_PRIV_ALG_NULL) {
                 rc = do_bulk_privacy(grctx->src_ctx->gsc_mechctx, desc, 0,
-                                     bsdv->bsd_priv_alg, bsdv);
+                                     grctx->src_reqbsd->bsd_priv_alg,
+                                     grctx->src_reqbsd);
                 if (rc) {
                         CERROR("bulk write: server failed to decrypt data\n");
                         RETURN(rc);
                 }
         }
 
+        /* verify bulk data checksum */
         rc = bulk_csum_svc(desc, req->rq_bulk_read,
-                           req->rq_reqbuf, voff, rs->rs_repbuf, roff);
+                           grctx->src_reqbsd, grctx->src_reqbsd_size,
+                           grctx->src_repbsd, grctx->src_repbsd_size);
 
         RETURN(rc);
 }
@@ -308,40 +324,36 @@ int gss_svc_unwrap_bulk(struct ptlrpc_request *req,
 int gss_svc_wrap_bulk(struct ptlrpc_request *req,
                       struct ptlrpc_bulk_desc *desc)
 {
-        struct ptlrpc_reply_state    *rs = req->rq_reply_state;
         struct gss_svc_reqctx        *grctx;
-        struct ptlrpc_bulk_sec_desc  *bsdv, *bsdr;
-        int                           voff, roff, rc;
+        int                           rc;
         ENTRY;
 
-        LASSERT(rs);
+        LASSERT(req->rq_svc_ctx);
+        LASSERT(req->rq_pack_bulk);
         LASSERT(req->rq_bulk_read);
 
-        if (SEC_FLAVOR_SVC(req->rq_sec_flavor) == SPTLRPC_SVC_PRIV) {
-                voff = req->rq_reqbuf->lm_bufcount - 1;
-                roff = rs->rs_repbuf->lm_bufcount - 1;
-        } else {
-                voff = req->rq_reqbuf->lm_bufcount - 2;
-                roff = rs->rs_repbuf->lm_bufcount - 2;
-        }
+        grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
+
+        LASSERT(grctx->src_reqbsd);
+        LASSERT(grctx->src_repbsd);
+        LASSERT(grctx->src_ctx);
+        LASSERT(grctx->src_ctx->gsc_mechctx);
 
+        /* generate bulk data checksum */
         rc = bulk_csum_svc(desc, req->rq_bulk_read,
-                           req->rq_reqbuf, voff, rs->rs_repbuf, roff);
+                           grctx->src_reqbsd, grctx->src_reqbsd_size,
+                           grctx->src_repbsd, grctx->src_repbsd_size);
         if (rc)
                 RETURN(rc);
 
-        bsdv = lustre_msg_buf(req->rq_reqbuf, voff, sizeof(*bsdv));
-        if (bsdv->bsd_priv_alg != BULK_PRIV_ALG_NULL) {
-                grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
-                LASSERT(grctx->src_ctx);
-                LASSERT(grctx->src_ctx->gsc_mechctx);
-
-                bsdr = lustre_msg_buf(rs->rs_repbuf, roff, sizeof(*bsdr));
-
+        /* encrypt bulk data if required */
+        if (grctx->src_reqbsd->bsd_priv_alg != BULK_PRIV_ALG_NULL) {
                 rc = do_bulk_privacy(grctx->src_ctx->gsc_mechctx, desc, 1,
-                                     bsdv->bsd_priv_alg, bsdr);
+                                     grctx->src_reqbsd->bsd_priv_alg,
+                                     grctx->src_repbsd);
                 if (rc)
-                        CERROR("bulk read: server failed to encrypt data\n");
+                        CERROR("bulk read: server failed to encrypt data: "
+                               "rc %d\n", rc);
         }
 
         RETURN(rc);