linux/net/sunrpc/auth_gss/gss_krb5_crypto.c
<<
>>
Prefs
   1/*
   2 *  linux/net/sunrpc/gss_krb5_crypto.c
   3 *
   4 *  Copyright (c) 2000-2008 The Regents of the University of Michigan.
   5 *  All rights reserved.
   6 *
   7 *  Andy Adamson   <andros@umich.edu>
   8 *  Bruce Fields   <bfields@umich.edu>
   9 */
  10
  11/*
  12 * Copyright (C) 1998 by the FundsXpress, INC.
  13 *
  14 * All rights reserved.
  15 *
  16 * Export of this software from the United States of America may require
  17 * a specific license from the United States Government.  It is the
  18 * responsibility of any person or organization contemplating export to
  19 * obtain such a license before exporting.
  20 *
  21 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
  22 * distribute this software and its documentation for any purpose and
  23 * without fee is hereby granted, provided that the above copyright
  24 * notice appear in all copies and that both that copyright notice and
  25 * this permission notice appear in supporting documentation, and that
  26 * the name of FundsXpress. not be used in advertising or publicity pertaining
  27 * to distribution of the software without specific, written prior
  28 * permission.  FundsXpress makes no representations about the suitability of
  29 * this software for any purpose.  It is provided "as is" without express
  30 * or implied warranty.
  31 *
  32 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  33 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  34 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  35 */
  36
  37#include <linux/err.h>
  38#include <linux/types.h>
  39#include <linux/mm.h>
  40#include <linux/scatterlist.h>
  41#include <linux/crypto.h>
  42#include <linux/highmem.h>
  43#include <linux/pagemap.h>
  44#include <linux/random.h>
  45#include <linux/sunrpc/gss_krb5.h>
  46#include <linux/sunrpc/xdr.h>
  47
  48#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
  49# define RPCDBG_FACILITY        RPCDBG_AUTH
  50#endif
  51
  52u32
  53krb5_encrypt(
  54        struct crypto_blkcipher *tfm,
  55        void * iv,
  56        void * in,
  57        void * out,
  58        int length)
  59{
  60        u32 ret = -EINVAL;
  61        struct scatterlist sg[1];
  62        u8 local_iv[GSS_KRB5_MAX_BLOCKSIZE] = {0};
  63        struct blkcipher_desc desc = { .tfm = tfm, .info = local_iv };
  64
  65        if (length % crypto_blkcipher_blocksize(tfm) != 0)
  66                goto out;
  67
  68        if (crypto_blkcipher_ivsize(tfm) > GSS_KRB5_MAX_BLOCKSIZE) {
  69                dprintk("RPC:       gss_k5encrypt: tfm iv size too large %d\n",
  70                        crypto_blkcipher_ivsize(tfm));
  71                goto out;
  72        }
  73
  74        if (iv)
  75                memcpy(local_iv, iv, crypto_blkcipher_ivsize(tfm));
  76
  77        memcpy(out, in, length);
  78        sg_init_one(sg, out, length);
  79
  80        ret = crypto_blkcipher_encrypt_iv(&desc, sg, sg, length);
  81out:
  82        dprintk("RPC:       krb5_encrypt returns %d\n", ret);
  83        return ret;
  84}
  85
  86u32
  87krb5_decrypt(
  88     struct crypto_blkcipher *tfm,
  89     void * iv,
  90     void * in,
  91     void * out,
  92     int length)
  93{
  94        u32 ret = -EINVAL;
  95        struct scatterlist sg[1];
  96        u8 local_iv[GSS_KRB5_MAX_BLOCKSIZE] = {0};
  97        struct blkcipher_desc desc = { .tfm = tfm, .info = local_iv };
  98
  99        if (length % crypto_blkcipher_blocksize(tfm) != 0)
 100                goto out;
 101
 102        if (crypto_blkcipher_ivsize(tfm) > GSS_KRB5_MAX_BLOCKSIZE) {
 103                dprintk("RPC:       gss_k5decrypt: tfm iv size too large %d\n",
 104                        crypto_blkcipher_ivsize(tfm));
 105                goto out;
 106        }
 107        if (iv)
 108                memcpy(local_iv,iv, crypto_blkcipher_ivsize(tfm));
 109
 110        memcpy(out, in, length);
 111        sg_init_one(sg, out, length);
 112
 113        ret = crypto_blkcipher_decrypt_iv(&desc, sg, sg, length);
 114out:
 115        dprintk("RPC:       gss_k5decrypt returns %d\n",ret);
 116        return ret;
 117}
 118
 119static int
 120checksummer(struct scatterlist *sg, void *data)
 121{
 122        struct hash_desc *desc = data;
 123
 124        return crypto_hash_update(desc, sg, sg->length);
 125}
 126
 127static int
 128arcfour_hmac_md5_usage_to_salt(unsigned int usage, u8 salt[4])
 129{
 130        unsigned int ms_usage;
 131
 132        switch (usage) {
 133        case KG_USAGE_SIGN:
 134                ms_usage = 15;
 135                break;
 136        case KG_USAGE_SEAL:
 137                ms_usage = 13;
 138                break;
 139        default:
 140                return -EINVAL;
 141        }
 142        salt[0] = (ms_usage >> 0) & 0xff;
 143        salt[1] = (ms_usage >> 8) & 0xff;
 144        salt[2] = (ms_usage >> 16) & 0xff;
 145        salt[3] = (ms_usage >> 24) & 0xff;
 146
 147        return 0;
 148}
 149
 150static u32
 151make_checksum_hmac_md5(struct krb5_ctx *kctx, char *header, int hdrlen,
 152                       struct xdr_buf *body, int body_offset, u8 *cksumkey,
 153                       unsigned int usage, struct xdr_netobj *cksumout)
 154{
 155        struct hash_desc                desc;
 156        struct scatterlist              sg[1];
 157        int err;
 158        u8 checksumdata[GSS_KRB5_MAX_CKSUM_LEN];
 159        u8 rc4salt[4];
 160        struct crypto_hash *md5;
 161        struct crypto_hash *hmac_md5;
 162
 163        if (cksumkey == NULL)
 164                return GSS_S_FAILURE;
 165
 166        if (cksumout->len < kctx->gk5e->cksumlength) {
 167                dprintk("%s: checksum buffer length, %u, too small for %s\n",
 168                        __func__, cksumout->len, kctx->gk5e->name);
 169                return GSS_S_FAILURE;
 170        }
 171
 172        if (arcfour_hmac_md5_usage_to_salt(usage, rc4salt)) {
 173                dprintk("%s: invalid usage value %u\n", __func__, usage);
 174                return GSS_S_FAILURE;
 175        }
 176
 177        md5 = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
 178        if (IS_ERR(md5))
 179                return GSS_S_FAILURE;
 180
 181        hmac_md5 = crypto_alloc_hash(kctx->gk5e->cksum_name, 0,
 182                                     CRYPTO_ALG_ASYNC);
 183        if (IS_ERR(hmac_md5)) {
 184                crypto_free_hash(md5);
 185                return GSS_S_FAILURE;
 186        }
 187
 188        desc.tfm = md5;
 189        desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
 190
 191        err = crypto_hash_init(&desc);
 192        if (err)
 193                goto out;
 194        sg_init_one(sg, rc4salt, 4);
 195        err = crypto_hash_update(&desc, sg, 4);
 196        if (err)
 197                goto out;
 198
 199        sg_init_one(sg, header, hdrlen);
 200        err = crypto_hash_update(&desc, sg, hdrlen);
 201        if (err)
 202                goto out;
 203        err = xdr_process_buf(body, body_offset, body->len - body_offset,
 204                              checksummer, &desc);
 205        if (err)
 206                goto out;
 207        err = crypto_hash_final(&desc, checksumdata);
 208        if (err)
 209                goto out;
 210
 211        desc.tfm = hmac_md5;
 212        desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
 213
 214        err = crypto_hash_init(&desc);
 215        if (err)
 216                goto out;
 217        err = crypto_hash_setkey(hmac_md5, cksumkey, kctx->gk5e->keylength);
 218        if (err)
 219                goto out;
 220
 221        sg_init_one(sg, checksumdata, crypto_hash_digestsize(md5));
 222        err = crypto_hash_digest(&desc, sg, crypto_hash_digestsize(md5),
 223                                 checksumdata);
 224        if (err)
 225                goto out;
 226
 227        memcpy(cksumout->data, checksumdata, kctx->gk5e->cksumlength);
 228        cksumout->len = kctx->gk5e->cksumlength;
 229out:
 230        crypto_free_hash(md5);
 231        crypto_free_hash(hmac_md5);
 232        return err ? GSS_S_FAILURE : 0;
 233}
 234
 235/*
 236 * checksum the plaintext data and hdrlen bytes of the token header
 237 * The checksum is performed over the first 8 bytes of the
 238 * gss token header and then over the data body
 239 */
 240u32
 241make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen,
 242              struct xdr_buf *body, int body_offset, u8 *cksumkey,
 243              unsigned int usage, struct xdr_netobj *cksumout)
 244{
 245        struct hash_desc                desc;
 246        struct scatterlist              sg[1];
 247        int err;
 248        u8 checksumdata[GSS_KRB5_MAX_CKSUM_LEN];
 249        unsigned int checksumlen;
 250
 251        if (kctx->gk5e->ctype == CKSUMTYPE_HMAC_MD5_ARCFOUR)
 252                return make_checksum_hmac_md5(kctx, header, hdrlen,
 253                                              body, body_offset,
 254                                              cksumkey, usage, cksumout);
 255
 256        if (cksumout->len < kctx->gk5e->cksumlength) {
 257                dprintk("%s: checksum buffer length, %u, too small for %s\n",
 258                        __func__, cksumout->len, kctx->gk5e->name);
 259                return GSS_S_FAILURE;
 260        }
 261
 262        desc.tfm = crypto_alloc_hash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC);
 263        if (IS_ERR(desc.tfm))
 264                return GSS_S_FAILURE;
 265        desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
 266
 267        checksumlen = crypto_hash_digestsize(desc.tfm);
 268
 269        if (cksumkey != NULL) {
 270                err = crypto_hash_setkey(desc.tfm, cksumkey,
 271                                         kctx->gk5e->keylength);
 272                if (err)
 273                        goto out;
 274        }
 275
 276        err = crypto_hash_init(&desc);
 277        if (err)
 278                goto out;
 279        sg_init_one(sg, header, hdrlen);
 280        err = crypto_hash_update(&desc, sg, hdrlen);
 281        if (err)
 282                goto out;
 283        err = xdr_process_buf(body, body_offset, body->len - body_offset,
 284                              checksummer, &desc);
 285        if (err)
 286                goto out;
 287        err = crypto_hash_final(&desc, checksumdata);
 288        if (err)
 289                goto out;
 290
 291        switch (kctx->gk5e->ctype) {
 292        case CKSUMTYPE_RSA_MD5:
 293                err = kctx->gk5e->encrypt(kctx->seq, NULL, checksumdata,
 294                                          checksumdata, checksumlen);
 295                if (err)
 296                        goto out;
 297                memcpy(cksumout->data,
 298                       checksumdata + checksumlen - kctx->gk5e->cksumlength,
 299                       kctx->gk5e->cksumlength);
 300                break;
 301        case CKSUMTYPE_HMAC_SHA1_DES3:
 302                memcpy(cksumout->data, checksumdata, kctx->gk5e->cksumlength);
 303                break;
 304        default:
 305                BUG();
 306                break;
 307        }
 308        cksumout->len = kctx->gk5e->cksumlength;
 309out:
 310        crypto_free_hash(desc.tfm);
 311        return err ? GSS_S_FAILURE : 0;
 312}
 313
 314/*
 315 * checksum the plaintext data and hdrlen bytes of the token header
 316 * Per rfc4121, sec. 4.2.4, the checksum is performed over the data
 317 * body then over the first 16 octets of the MIC token
 318 * Inclusion of the header data in the calculation of the
 319 * checksum is optional.
 320 */
 321u32
 322make_checksum_v2(struct krb5_ctx *kctx, char *header, int hdrlen,
 323                 struct xdr_buf *body, int body_offset, u8 *cksumkey,
 324                 unsigned int usage, struct xdr_netobj *cksumout)
 325{
 326        struct hash_desc desc;
 327        struct scatterlist sg[1];
 328        int err;
 329        u8 checksumdata[GSS_KRB5_MAX_CKSUM_LEN];
 330        unsigned int checksumlen;
 331
 332        if (kctx->gk5e->keyed_cksum == 0) {
 333                dprintk("%s: expected keyed hash for %s\n",
 334                        __func__, kctx->gk5e->name);
 335                return GSS_S_FAILURE;
 336        }
 337        if (cksumkey == NULL) {
 338                dprintk("%s: no key supplied for %s\n",
 339                        __func__, kctx->gk5e->name);
 340                return GSS_S_FAILURE;
 341        }
 342
 343        desc.tfm = crypto_alloc_hash(kctx->gk5e->cksum_name, 0,
 344                                                        CRYPTO_ALG_ASYNC);
 345        if (IS_ERR(desc.tfm))
 346                return GSS_S_FAILURE;
 347        checksumlen = crypto_hash_digestsize(desc.tfm);
 348        desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
 349
 350        err = crypto_hash_setkey(desc.tfm, cksumkey, kctx->gk5e->keylength);
 351        if (err)
 352                goto out;
 353
 354        err = crypto_hash_init(&desc);
 355        if (err)
 356                goto out;
 357        err = xdr_process_buf(body, body_offset, body->len - body_offset,
 358                              checksummer, &desc);
 359        if (err)
 360                goto out;
 361        if (header != NULL) {
 362                sg_init_one(sg, header, hdrlen);
 363                err = crypto_hash_update(&desc, sg, hdrlen);
 364                if (err)
 365                        goto out;
 366        }
 367        err = crypto_hash_final(&desc, checksumdata);
 368        if (err)
 369                goto out;
 370
 371        cksumout->len = kctx->gk5e->cksumlength;
 372
 373        switch (kctx->gk5e->ctype) {
 374        case CKSUMTYPE_HMAC_SHA1_96_AES128:
 375        case CKSUMTYPE_HMAC_SHA1_96_AES256:
 376                /* note that this truncates the hash */
 377                memcpy(cksumout->data, checksumdata, kctx->gk5e->cksumlength);
 378                break;
 379        default:
 380                BUG();
 381                break;
 382        }
 383out:
 384        crypto_free_hash(desc.tfm);
 385        return err ? GSS_S_FAILURE : 0;
 386}
 387
 388struct encryptor_desc {
 389        u8 iv[GSS_KRB5_MAX_BLOCKSIZE];
 390        struct blkcipher_desc desc;
 391        int pos;
 392        struct xdr_buf *outbuf;
 393        struct page **pages;
 394        struct scatterlist infrags[4];
 395        struct scatterlist outfrags[4];
 396        int fragno;
 397        int fraglen;
 398};
 399
 400static int
 401encryptor(struct scatterlist *sg, void *data)
 402{
 403        struct encryptor_desc *desc = data;
 404        struct xdr_buf *outbuf = desc->outbuf;
 405        struct page *in_page;
 406        int thislen = desc->fraglen + sg->length;
 407        int fraglen, ret;
 408        int page_pos;
 409
 410        /* Worst case is 4 fragments: head, end of page 1, start
 411         * of page 2, tail.  Anything more is a bug. */
 412        BUG_ON(desc->fragno > 3);
 413
 414        page_pos = desc->pos - outbuf->head[0].iov_len;
 415        if (page_pos >= 0 && page_pos < outbuf->page_len) {
 416                /* pages are not in place: */
 417                int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT;
 418                in_page = desc->pages[i];
 419        } else {
 420                in_page = sg_page(sg);
 421        }
 422        sg_set_page(&desc->infrags[desc->fragno], in_page, sg->length,
 423                    sg->offset);
 424        sg_set_page(&desc->outfrags[desc->fragno], sg_page(sg), sg->length,
 425                    sg->offset);
 426        desc->fragno++;
 427        desc->fraglen += sg->length;
 428        desc->pos += sg->length;
 429
 430        fraglen = thislen & (crypto_blkcipher_blocksize(desc->desc.tfm) - 1);
 431        thislen -= fraglen;
 432
 433        if (thislen == 0)
 434                return 0;
 435
 436        sg_mark_end(&desc->infrags[desc->fragno - 1]);
 437        sg_mark_end(&desc->outfrags[desc->fragno - 1]);
 438
 439        ret = crypto_blkcipher_encrypt_iv(&desc->desc, desc->outfrags,
 440                                          desc->infrags, thislen);
 441        if (ret)
 442                return ret;
 443
 444        sg_init_table(desc->infrags, 4);
 445        sg_init_table(desc->outfrags, 4);
 446
 447        if (fraglen) {
 448                sg_set_page(&desc->outfrags[0], sg_page(sg), fraglen,
 449                                sg->offset + sg->length - fraglen);
 450                desc->infrags[0] = desc->outfrags[0];
 451                sg_assign_page(&desc->infrags[0], in_page);
 452                desc->fragno = 1;
 453                desc->fraglen = fraglen;
 454        } else {
 455                desc->fragno = 0;
 456                desc->fraglen = 0;
 457        }
 458        return 0;
 459}
 460
 461int
 462gss_encrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *buf,
 463                    int offset, struct page **pages)
 464{
 465        int ret;
 466        struct encryptor_desc desc;
 467
 468        BUG_ON((buf->len - offset) % crypto_blkcipher_blocksize(tfm) != 0);
 469
 470        memset(desc.iv, 0, sizeof(desc.iv));
 471        desc.desc.tfm = tfm;
 472        desc.desc.info = desc.iv;
 473        desc.desc.flags = 0;
 474        desc.pos = offset;
 475        desc.outbuf = buf;
 476        desc.pages = pages;
 477        desc.fragno = 0;
 478        desc.fraglen = 0;
 479
 480        sg_init_table(desc.infrags, 4);
 481        sg_init_table(desc.outfrags, 4);
 482
 483        ret = xdr_process_buf(buf, offset, buf->len - offset, encryptor, &desc);
 484        return ret;
 485}
 486
 487struct decryptor_desc {
 488        u8 iv[GSS_KRB5_MAX_BLOCKSIZE];
 489        struct blkcipher_desc desc;
 490        struct scatterlist frags[4];
 491        int fragno;
 492        int fraglen;
 493};
 494
 495static int
 496decryptor(struct scatterlist *sg, void *data)
 497{
 498        struct decryptor_desc *desc = data;
 499        int thislen = desc->fraglen + sg->length;
 500        int fraglen, ret;
 501
 502        /* Worst case is 4 fragments: head, end of page 1, start
 503         * of page 2, tail.  Anything more is a bug. */
 504        BUG_ON(desc->fragno > 3);
 505        sg_set_page(&desc->frags[desc->fragno], sg_page(sg), sg->length,
 506                    sg->offset);
 507        desc->fragno++;
 508        desc->fraglen += sg->length;
 509
 510        fraglen = thislen & (crypto_blkcipher_blocksize(desc->desc.tfm) - 1);
 511        thislen -= fraglen;
 512
 513        if (thislen == 0)
 514                return 0;
 515
 516        sg_mark_end(&desc->frags[desc->fragno - 1]);
 517
 518        ret = crypto_blkcipher_decrypt_iv(&desc->desc, desc->frags,
 519                                          desc->frags, thislen);
 520        if (ret)
 521                return ret;
 522
 523        sg_init_table(desc->frags, 4);
 524
 525        if (fraglen) {
 526                sg_set_page(&desc->frags[0], sg_page(sg), fraglen,
 527                                sg->offset + sg->length - fraglen);
 528                desc->fragno = 1;
 529                desc->fraglen = fraglen;
 530        } else {
 531                desc->fragno = 0;
 532                desc->fraglen = 0;
 533        }
 534        return 0;
 535}
 536
 537int
 538gss_decrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *buf,
 539                    int offset)
 540{
 541        struct decryptor_desc desc;
 542
 543        /* XXXJBF: */
 544        BUG_ON((buf->len - offset) % crypto_blkcipher_blocksize(tfm) != 0);
 545
 546        memset(desc.iv, 0, sizeof(desc.iv));
 547        desc.desc.tfm = tfm;
 548        desc.desc.info = desc.iv;
 549        desc.desc.flags = 0;
 550        desc.fragno = 0;
 551        desc.fraglen = 0;
 552
 553        sg_init_table(desc.frags, 4);
 554
 555        return xdr_process_buf(buf, offset, buf->len - offset, decryptor, &desc);
 556}
 557
 558/*
 559 * This function makes the assumption that it was ultimately called
 560 * from gss_wrap().
 561 *
 562 * The client auth_gss code moves any existing tail data into a
 563 * separate page before calling gss_wrap.
 564 * The server svcauth_gss code ensures that both the head and the
 565 * tail have slack space of RPC_MAX_AUTH_SIZE before calling gss_wrap.
 566 *
 567 * Even with that guarantee, this function may be called more than
 568 * once in the processing of gss_wrap().  The best we can do is
 569 * verify at compile-time (see GSS_KRB5_SLACK_CHECK) that the
 570 * largest expected shift will fit within RPC_MAX_AUTH_SIZE.
 571 * At run-time we can verify that a single invocation of this
 572 * function doesn't attempt to use more the RPC_MAX_AUTH_SIZE.
 573 */
 574
 575int
 576xdr_extend_head(struct xdr_buf *buf, unsigned int base, unsigned int shiftlen)
 577{
 578        u8 *p;
 579
 580        if (shiftlen == 0)
 581                return 0;
 582
 583        BUILD_BUG_ON(GSS_KRB5_MAX_SLACK_NEEDED > RPC_MAX_AUTH_SIZE);
 584        BUG_ON(shiftlen > RPC_MAX_AUTH_SIZE);
 585
 586        p = buf->head[0].iov_base + base;
 587
 588        memmove(p + shiftlen, p, buf->head[0].iov_len - base);
 589
 590        buf->head[0].iov_len += shiftlen;
 591        buf->len += shiftlen;
 592
 593        return 0;
 594}
 595
 596static u32
 597gss_krb5_cts_crypt(struct crypto_blkcipher *cipher, struct xdr_buf *buf,
 598                   u32 offset, u8 *iv, struct page **pages, int encrypt)
 599{
 600        u32 ret;
 601        struct scatterlist sg[1];
 602        struct blkcipher_desc desc = { .tfm = cipher, .info = iv };
 603        u8 data[GSS_KRB5_MAX_BLOCKSIZE * 2];
 604        struct page **save_pages;
 605        u32 len = buf->len - offset;
 606
 607        if (len > ARRAY_SIZE(data)) {
 608                WARN_ON(0);
 609                return -ENOMEM;
 610        }
 611
 612        /*
 613         * For encryption, we want to read from the cleartext
 614         * page cache pages, and write the encrypted data to
 615         * the supplied xdr_buf pages.
 616         */
 617        save_pages = buf->pages;
 618        if (encrypt)
 619                buf->pages = pages;
 620
 621        ret = read_bytes_from_xdr_buf(buf, offset, data, len);
 622        buf->pages = save_pages;
 623        if (ret)
 624                goto out;
 625
 626        sg_init_one(sg, data, len);
 627
 628        if (encrypt)
 629                ret = crypto_blkcipher_encrypt_iv(&desc, sg, sg, len);
 630        else
 631                ret = crypto_blkcipher_decrypt_iv(&desc, sg, sg, len);
 632
 633        if (ret)
 634                goto out;
 635
 636        ret = write_bytes_to_xdr_buf(buf, offset, data, len);
 637
 638out:
 639        return ret;
 640}
 641
 642u32
 643gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset,
 644                     struct xdr_buf *buf, struct page **pages)
 645{
 646        u32 err;
 647        struct xdr_netobj hmac;
 648        u8 *cksumkey;
 649        u8 *ecptr;
 650        struct crypto_blkcipher *cipher, *aux_cipher;
 651        int blocksize;
 652        struct page **save_pages;
 653        int nblocks, nbytes;
 654        struct encryptor_desc desc;
 655        u32 cbcbytes;
 656        unsigned int usage;
 657
 658        if (kctx->initiate) {
 659                cipher = kctx->initiator_enc;
 660                aux_cipher = kctx->initiator_enc_aux;
 661                cksumkey = kctx->initiator_integ;
 662                usage = KG_USAGE_INITIATOR_SEAL;
 663        } else {
 664                cipher = kctx->acceptor_enc;
 665                aux_cipher = kctx->acceptor_enc_aux;
 666                cksumkey = kctx->acceptor_integ;
 667                usage = KG_USAGE_ACCEPTOR_SEAL;
 668        }
 669        blocksize = crypto_blkcipher_blocksize(cipher);
 670
 671        /* hide the gss token header and insert the confounder */
 672        offset += GSS_KRB5_TOK_HDR_LEN;
 673        if (xdr_extend_head(buf, offset, kctx->gk5e->conflen))
 674                return GSS_S_FAILURE;
 675        gss_krb5_make_confounder(buf->head[0].iov_base + offset, kctx->gk5e->conflen);
 676        offset -= GSS_KRB5_TOK_HDR_LEN;
 677
 678        if (buf->tail[0].iov_base != NULL) {
 679                ecptr = buf->tail[0].iov_base + buf->tail[0].iov_len;
 680        } else {
 681                buf->tail[0].iov_base = buf->head[0].iov_base
 682                                                        + buf->head[0].iov_len;
 683                buf->tail[0].iov_len = 0;
 684                ecptr = buf->tail[0].iov_base;
 685        }
 686
 687        /* copy plaintext gss token header after filler (if any) */
 688        memcpy(ecptr, buf->head[0].iov_base + offset, GSS_KRB5_TOK_HDR_LEN);
 689        buf->tail[0].iov_len += GSS_KRB5_TOK_HDR_LEN;
 690        buf->len += GSS_KRB5_TOK_HDR_LEN;
 691
 692        /* Do the HMAC */
 693        hmac.len = GSS_KRB5_MAX_CKSUM_LEN;
 694        hmac.data = buf->tail[0].iov_base + buf->tail[0].iov_len;
 695
 696        /*
 697         * When we are called, pages points to the real page cache
 698         * data -- which we can't go and encrypt!  buf->pages points
 699         * to scratch pages which we are going to send off to the
 700         * client/server.  Swap in the plaintext pages to calculate
 701         * the hmac.
 702         */
 703        save_pages = buf->pages;
 704        buf->pages = pages;
 705
 706        err = make_checksum_v2(kctx, NULL, 0, buf,
 707                               offset + GSS_KRB5_TOK_HDR_LEN,
 708                               cksumkey, usage, &hmac);
 709        buf->pages = save_pages;
 710        if (err)
 711                return GSS_S_FAILURE;
 712
 713        nbytes = buf->len - offset - GSS_KRB5_TOK_HDR_LEN;
 714        nblocks = (nbytes + blocksize - 1) / blocksize;
 715        cbcbytes = 0;
 716        if (nblocks > 2)
 717                cbcbytes = (nblocks - 2) * blocksize;
 718
 719        memset(desc.iv, 0, sizeof(desc.iv));
 720
 721        if (cbcbytes) {
 722                desc.pos = offset + GSS_KRB5_TOK_HDR_LEN;
 723                desc.fragno = 0;
 724                desc.fraglen = 0;
 725                desc.pages = pages;
 726                desc.outbuf = buf;
 727                desc.desc.info = desc.iv;
 728                desc.desc.flags = 0;
 729                desc.desc.tfm = aux_cipher;
 730
 731                sg_init_table(desc.infrags, 4);
 732                sg_init_table(desc.outfrags, 4);
 733
 734                err = xdr_process_buf(buf, offset + GSS_KRB5_TOK_HDR_LEN,
 735                                      cbcbytes, encryptor, &desc);
 736                if (err)
 737                        goto out_err;
 738        }
 739
 740        /* Make sure IV carries forward from any CBC results. */
 741        err = gss_krb5_cts_crypt(cipher, buf,
 742                                 offset + GSS_KRB5_TOK_HDR_LEN + cbcbytes,
 743                                 desc.iv, pages, 1);
 744        if (err) {
 745                err = GSS_S_FAILURE;
 746                goto out_err;
 747        }
 748
 749        /* Now update buf to account for HMAC */
 750        buf->tail[0].iov_len += kctx->gk5e->cksumlength;
 751        buf->len += kctx->gk5e->cksumlength;
 752
 753out_err:
 754        if (err)
 755                err = GSS_S_FAILURE;
 756        return err;
 757}
 758
 759u32
 760gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf,
 761                     u32 *headskip, u32 *tailskip)
 762{
 763        struct xdr_buf subbuf;
 764        u32 ret = 0;
 765        u8 *cksum_key;
 766        struct crypto_blkcipher *cipher, *aux_cipher;
 767        struct xdr_netobj our_hmac_obj;
 768        u8 our_hmac[GSS_KRB5_MAX_CKSUM_LEN];
 769        u8 pkt_hmac[GSS_KRB5_MAX_CKSUM_LEN];
 770        int nblocks, blocksize, cbcbytes;
 771        struct decryptor_desc desc;
 772        unsigned int usage;
 773
 774        if (kctx->initiate) {
 775                cipher = kctx->acceptor_enc;
 776                aux_cipher = kctx->acceptor_enc_aux;
 777                cksum_key = kctx->acceptor_integ;
 778                usage = KG_USAGE_ACCEPTOR_SEAL;
 779        } else {
 780                cipher = kctx->initiator_enc;
 781                aux_cipher = kctx->initiator_enc_aux;
 782                cksum_key = kctx->initiator_integ;
 783                usage = KG_USAGE_INITIATOR_SEAL;
 784        }
 785        blocksize = crypto_blkcipher_blocksize(cipher);
 786
 787
 788        /* create a segment skipping the header and leaving out the checksum */
 789        xdr_buf_subsegment(buf, &subbuf, offset + GSS_KRB5_TOK_HDR_LEN,
 790                                    (buf->len - offset - GSS_KRB5_TOK_HDR_LEN -
 791                                     kctx->gk5e->cksumlength));
 792
 793        nblocks = (subbuf.len + blocksize - 1) / blocksize;
 794
 795        cbcbytes = 0;
 796        if (nblocks > 2)
 797                cbcbytes = (nblocks - 2) * blocksize;
 798
 799        memset(desc.iv, 0, sizeof(desc.iv));
 800
 801        if (cbcbytes) {
 802                desc.fragno = 0;
 803                desc.fraglen = 0;
 804                desc.desc.info = desc.iv;
 805                desc.desc.flags = 0;
 806                desc.desc.tfm = aux_cipher;
 807
 808                sg_init_table(desc.frags, 4);
 809
 810                ret = xdr_process_buf(&subbuf, 0, cbcbytes, decryptor, &desc);
 811                if (ret)
 812                        goto out_err;
 813        }
 814
 815        /* Make sure IV carries forward from any CBC results. */
 816        ret = gss_krb5_cts_crypt(cipher, &subbuf, cbcbytes, desc.iv, NULL, 0);
 817        if (ret)
 818                goto out_err;
 819
 820
 821        /* Calculate our hmac over the plaintext data */
 822        our_hmac_obj.len = sizeof(our_hmac);
 823        our_hmac_obj.data = our_hmac;
 824
 825        ret = make_checksum_v2(kctx, NULL, 0, &subbuf, 0,
 826                               cksum_key, usage, &our_hmac_obj);
 827        if (ret)
 828                goto out_err;
 829
 830        /* Get the packet's hmac value */
 831        ret = read_bytes_from_xdr_buf(buf, buf->len - kctx->gk5e->cksumlength,
 832                                      pkt_hmac, kctx->gk5e->cksumlength);
 833        if (ret)
 834                goto out_err;
 835
 836        if (memcmp(pkt_hmac, our_hmac, kctx->gk5e->cksumlength) != 0) {
 837                ret = GSS_S_BAD_SIG;
 838                goto out_err;
 839        }
 840        *headskip = kctx->gk5e->conflen;
 841        *tailskip = kctx->gk5e->cksumlength;
 842out_err:
 843        if (ret && ret != GSS_S_BAD_SIG)
 844                ret = GSS_S_FAILURE;
 845        return ret;
 846}
 847
 848/*
 849 * Compute Kseq given the initial session key and the checksum.
 850 * Set the key of the given cipher.
 851 */
 852int
 853krb5_rc4_setup_seq_key(struct krb5_ctx *kctx, struct crypto_blkcipher *cipher,
 854                       unsigned char *cksum)
 855{
 856        struct crypto_hash *hmac;
 857        struct hash_desc desc;
 858        struct scatterlist sg[1];
 859        u8 Kseq[GSS_KRB5_MAX_KEYLEN];
 860        u32 zeroconstant = 0;
 861        int err;
 862
 863        dprintk("%s: entered\n", __func__);
 864
 865        hmac = crypto_alloc_hash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC);
 866        if (IS_ERR(hmac)) {
 867                dprintk("%s: error %ld, allocating hash '%s'\n",
 868                        __func__, PTR_ERR(hmac), kctx->gk5e->cksum_name);
 869                return PTR_ERR(hmac);
 870        }
 871
 872        desc.tfm = hmac;
 873        desc.flags = 0;
 874
 875        err = crypto_hash_init(&desc);
 876        if (err)
 877                goto out_err;
 878
 879        /* Compute intermediate Kseq from session key */
 880        err = crypto_hash_setkey(hmac, kctx->Ksess, kctx->gk5e->keylength);
 881        if (err)
 882                goto out_err;
 883
 884        sg_init_table(sg, 1);
 885        sg_set_buf(sg, &zeroconstant, 4);
 886
 887        err = crypto_hash_digest(&desc, sg, 4, Kseq);
 888        if (err)
 889                goto out_err;
 890
 891        /* Compute final Kseq from the checksum and intermediate Kseq */
 892        err = crypto_hash_setkey(hmac, Kseq, kctx->gk5e->keylength);
 893        if (err)
 894                goto out_err;
 895
 896        sg_set_buf(sg, cksum, 8);
 897
 898        err = crypto_hash_digest(&desc, sg, 8, Kseq);
 899        if (err)
 900                goto out_err;
 901
 902        err = crypto_blkcipher_setkey(cipher, Kseq, kctx->gk5e->keylength);
 903        if (err)
 904                goto out_err;
 905
 906        err = 0;
 907
 908out_err:
 909        crypto_free_hash(hmac);
 910        dprintk("%s: returning %d\n", __func__, err);
 911        return err;
 912}
 913
 914/*
 915 * Compute Kcrypt given the initial session key and the plaintext seqnum.
 916 * Set the key of cipher kctx->enc.
 917 */
 918int
 919krb5_rc4_setup_enc_key(struct krb5_ctx *kctx, struct crypto_blkcipher *cipher,
 920                       s32 seqnum)
 921{
 922        struct crypto_hash *hmac;
 923        struct hash_desc desc;
 924        struct scatterlist sg[1];
 925        u8 Kcrypt[GSS_KRB5_MAX_KEYLEN];
 926        u8 zeroconstant[4] = {0};
 927        u8 seqnumarray[4];
 928        int err, i;
 929
 930        dprintk("%s: entered, seqnum %u\n", __func__, seqnum);
 931
 932        hmac = crypto_alloc_hash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC);
 933        if (IS_ERR(hmac)) {
 934                dprintk("%s: error %ld, allocating hash '%s'\n",
 935                        __func__, PTR_ERR(hmac), kctx->gk5e->cksum_name);
 936                return PTR_ERR(hmac);
 937        }
 938
 939        desc.tfm = hmac;
 940        desc.flags = 0;
 941
 942        err = crypto_hash_init(&desc);
 943        if (err)
 944                goto out_err;
 945
 946        /* Compute intermediate Kcrypt from session key */
 947        for (i = 0; i < kctx->gk5e->keylength; i++)
 948                Kcrypt[i] = kctx->Ksess[i] ^ 0xf0;
 949
 950        err = crypto_hash_setkey(hmac, Kcrypt, kctx->gk5e->keylength);
 951        if (err)
 952                goto out_err;
 953
 954        sg_init_table(sg, 1);
 955        sg_set_buf(sg, zeroconstant, 4);
 956
 957        err = crypto_hash_digest(&desc, sg, 4, Kcrypt);
 958        if (err)
 959                goto out_err;
 960
 961        /* Compute final Kcrypt from the seqnum and intermediate Kcrypt */
 962        err = crypto_hash_setkey(hmac, Kcrypt, kctx->gk5e->keylength);
 963        if (err)
 964                goto out_err;
 965
 966        seqnumarray[0] = (unsigned char) ((seqnum >> 24) & 0xff);
 967        seqnumarray[1] = (unsigned char) ((seqnum >> 16) & 0xff);
 968        seqnumarray[2] = (unsigned char) ((seqnum >> 8) & 0xff);
 969        seqnumarray[3] = (unsigned char) ((seqnum >> 0) & 0xff);
 970
 971        sg_set_buf(sg, seqnumarray, 4);
 972
 973        err = crypto_hash_digest(&desc, sg, 4, Kcrypt);
 974        if (err)
 975                goto out_err;
 976
 977        err = crypto_blkcipher_setkey(cipher, Kcrypt, kctx->gk5e->keylength);
 978        if (err)
 979                goto out_err;
 980
 981        err = 0;
 982
 983out_err:
 984        crypto_free_hash(hmac);
 985        dprintk("%s: returning %d\n", __func__, err);
 986        return err;
 987}
 988
 989