Path: blob/master/net/sunrpc/auth_gss/gss_krb5_seqnum.c
15112 views
/*1* linux/net/sunrpc/gss_krb5_seqnum.c2*3* Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/util_seqnum.c4*5* Copyright (c) 2000 The Regents of the University of Michigan.6* All rights reserved.7*8* Andy Adamson <[email protected]>9*/1011/*12* Copyright 1993 by OpenVision Technologies, Inc.13*14* Permission to use, copy, modify, distribute, and sell this software15* and its documentation for any purpose is hereby granted without fee,16* provided that the above copyright notice appears in all copies and17* that both that copyright notice and this permission notice appear in18* supporting documentation, and that the name of OpenVision not be used19* in advertising or publicity pertaining to distribution of the software20* without specific, written prior permission. OpenVision makes no21* representations about the suitability of this software for any22* purpose. It is provided "as is" without express or implied warranty.23*24* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,25* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO26* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR27* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF28* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR29* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR30* PERFORMANCE OF THIS SOFTWARE.31*/3233#include <linux/types.h>34#include <linux/sunrpc/gss_krb5.h>35#include <linux/crypto.h>3637#ifdef RPC_DEBUG38# define RPCDBG_FACILITY RPCDBG_AUTH39#endif4041static s3242krb5_make_rc4_seq_num(struct krb5_ctx *kctx, int direction, s32 seqnum,43unsigned char *cksum, unsigned char *buf)44{45struct crypto_blkcipher *cipher;46unsigned char plain[8];47s32 code;4849dprintk("RPC: %s:\n", __func__);50cipher = crypto_alloc_blkcipher(kctx->gk5e->encrypt_name, 0,51CRYPTO_ALG_ASYNC);52if (IS_ERR(cipher))53return PTR_ERR(cipher);5455plain[0] = (unsigned char) ((seqnum >> 24) & 0xff);56plain[1] = (unsigned char) ((seqnum >> 16) & 0xff);57plain[2] = (unsigned char) ((seqnum >> 8) & 0xff);58plain[3] = (unsigned char) ((seqnum >> 0) & 0xff);59plain[4] = direction;60plain[5] = direction;61plain[6] = direction;62plain[7] = direction;6364code = krb5_rc4_setup_seq_key(kctx, cipher, cksum);65if (code)66goto out;6768code = krb5_encrypt(cipher, cksum, plain, buf, 8);69out:70crypto_free_blkcipher(cipher);71return code;72}73s3274krb5_make_seq_num(struct krb5_ctx *kctx,75struct crypto_blkcipher *key,76int direction,77u32 seqnum,78unsigned char *cksum, unsigned char *buf)79{80unsigned char plain[8];8182if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC)83return krb5_make_rc4_seq_num(kctx, direction, seqnum,84cksum, buf);8586plain[0] = (unsigned char) (seqnum & 0xff);87plain[1] = (unsigned char) ((seqnum >> 8) & 0xff);88plain[2] = (unsigned char) ((seqnum >> 16) & 0xff);89plain[3] = (unsigned char) ((seqnum >> 24) & 0xff);9091plain[4] = direction;92plain[5] = direction;93plain[6] = direction;94plain[7] = direction;9596return krb5_encrypt(key, cksum, plain, buf, 8);97}9899static s32100krb5_get_rc4_seq_num(struct krb5_ctx *kctx, unsigned char *cksum,101unsigned char *buf, int *direction, s32 *seqnum)102{103struct crypto_blkcipher *cipher;104unsigned char plain[8];105s32 code;106107dprintk("RPC: %s:\n", __func__);108cipher = crypto_alloc_blkcipher(kctx->gk5e->encrypt_name, 0,109CRYPTO_ALG_ASYNC);110if (IS_ERR(cipher))111return PTR_ERR(cipher);112113code = krb5_rc4_setup_seq_key(kctx, cipher, cksum);114if (code)115goto out;116117code = krb5_decrypt(cipher, cksum, buf, plain, 8);118if (code)119goto out;120121if ((plain[4] != plain[5]) || (plain[4] != plain[6])122|| (plain[4] != plain[7])) {123code = (s32)KG_BAD_SEQ;124goto out;125}126127*direction = plain[4];128129*seqnum = ((plain[0] << 24) | (plain[1] << 16) |130(plain[2] << 8) | (plain[3]));131out:132crypto_free_blkcipher(cipher);133return code;134}135136s32137krb5_get_seq_num(struct krb5_ctx *kctx,138unsigned char *cksum,139unsigned char *buf,140int *direction, u32 *seqnum)141{142s32 code;143unsigned char plain[8];144struct crypto_blkcipher *key = kctx->seq;145146dprintk("RPC: krb5_get_seq_num:\n");147148if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC)149return krb5_get_rc4_seq_num(kctx, cksum, buf,150direction, seqnum);151152if ((code = krb5_decrypt(key, cksum, buf, plain, 8)))153return code;154155if ((plain[4] != plain[5]) || (plain[4] != plain[6]) ||156(plain[4] != plain[7]))157return (s32)KG_BAD_SEQ;158159*direction = plain[4];160161*seqnum = ((plain[0]) |162(plain[1] << 8) | (plain[2] << 16) | (plain[3] << 24));163164return 0;165}166167168