18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci *  linux/net/sunrpc/gss_krb5_seqnum.c
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci *  Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/util_seqnum.c
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci *  Copyright (c) 2000 The Regents of the University of Michigan.
78c2ecf20Sopenharmony_ci *  All rights reserved.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci *  Andy Adamson   <andros@umich.edu>
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/*
138c2ecf20Sopenharmony_ci * Copyright 1993 by OpenVision Technologies, Inc.
148c2ecf20Sopenharmony_ci *
158c2ecf20Sopenharmony_ci * Permission to use, copy, modify, distribute, and sell this software
168c2ecf20Sopenharmony_ci * and its documentation for any purpose is hereby granted without fee,
178c2ecf20Sopenharmony_ci * provided that the above copyright notice appears in all copies and
188c2ecf20Sopenharmony_ci * that both that copyright notice and this permission notice appear in
198c2ecf20Sopenharmony_ci * supporting documentation, and that the name of OpenVision not be used
208c2ecf20Sopenharmony_ci * in advertising or publicity pertaining to distribution of the software
218c2ecf20Sopenharmony_ci * without specific, written prior permission. OpenVision makes no
228c2ecf20Sopenharmony_ci * representations about the suitability of this software for any
238c2ecf20Sopenharmony_ci * purpose.  It is provided "as is" without express or implied warranty.
248c2ecf20Sopenharmony_ci *
258c2ecf20Sopenharmony_ci * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
268c2ecf20Sopenharmony_ci * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
278c2ecf20Sopenharmony_ci * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
288c2ecf20Sopenharmony_ci * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
298c2ecf20Sopenharmony_ci * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
308c2ecf20Sopenharmony_ci * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
318c2ecf20Sopenharmony_ci * PERFORMANCE OF THIS SOFTWARE.
328c2ecf20Sopenharmony_ci */
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#include <crypto/skcipher.h>
358c2ecf20Sopenharmony_ci#include <linux/types.h>
368c2ecf20Sopenharmony_ci#include <linux/sunrpc/gss_krb5.h>
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
398c2ecf20Sopenharmony_ci# define RPCDBG_FACILITY        RPCDBG_AUTH
408c2ecf20Sopenharmony_ci#endif
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_cis32
438c2ecf20Sopenharmony_cikrb5_make_seq_num(struct krb5_ctx *kctx,
448c2ecf20Sopenharmony_ci		struct crypto_sync_skcipher *key,
458c2ecf20Sopenharmony_ci		int direction,
468c2ecf20Sopenharmony_ci		u32 seqnum,
478c2ecf20Sopenharmony_ci		unsigned char *cksum, unsigned char *buf)
488c2ecf20Sopenharmony_ci{
498c2ecf20Sopenharmony_ci	unsigned char *plain;
508c2ecf20Sopenharmony_ci	s32 code;
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	plain = kmalloc(8, GFP_NOFS);
538c2ecf20Sopenharmony_ci	if (!plain)
548c2ecf20Sopenharmony_ci		return -ENOMEM;
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	plain[0] = (unsigned char) (seqnum & 0xff);
578c2ecf20Sopenharmony_ci	plain[1] = (unsigned char) ((seqnum >> 8) & 0xff);
588c2ecf20Sopenharmony_ci	plain[2] = (unsigned char) ((seqnum >> 16) & 0xff);
598c2ecf20Sopenharmony_ci	plain[3] = (unsigned char) ((seqnum >> 24) & 0xff);
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	plain[4] = direction;
628c2ecf20Sopenharmony_ci	plain[5] = direction;
638c2ecf20Sopenharmony_ci	plain[6] = direction;
648c2ecf20Sopenharmony_ci	plain[7] = direction;
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	code = krb5_encrypt(key, cksum, plain, buf, 8);
678c2ecf20Sopenharmony_ci	kfree(plain);
688c2ecf20Sopenharmony_ci	return code;
698c2ecf20Sopenharmony_ci}
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cis32
728c2ecf20Sopenharmony_cikrb5_get_seq_num(struct krb5_ctx *kctx,
738c2ecf20Sopenharmony_ci	       unsigned char *cksum,
748c2ecf20Sopenharmony_ci	       unsigned char *buf,
758c2ecf20Sopenharmony_ci	       int *direction, u32 *seqnum)
768c2ecf20Sopenharmony_ci{
778c2ecf20Sopenharmony_ci	s32 code;
788c2ecf20Sopenharmony_ci	unsigned char *plain;
798c2ecf20Sopenharmony_ci	struct crypto_sync_skcipher *key = kctx->seq;
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	dprintk("RPC:       krb5_get_seq_num:\n");
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	plain = kmalloc(8, GFP_NOFS);
848c2ecf20Sopenharmony_ci	if (!plain)
858c2ecf20Sopenharmony_ci		return -ENOMEM;
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	if ((code = krb5_decrypt(key, cksum, buf, plain, 8)))
888c2ecf20Sopenharmony_ci		goto out;
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	if ((plain[4] != plain[5]) || (plain[4] != plain[6]) ||
918c2ecf20Sopenharmony_ci	    (plain[4] != plain[7])) {
928c2ecf20Sopenharmony_ci		code = (s32)KG_BAD_SEQ;
938c2ecf20Sopenharmony_ci		goto out;
948c2ecf20Sopenharmony_ci	}
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	*direction = plain[4];
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	*seqnum = ((plain[0]) |
998c2ecf20Sopenharmony_ci		   (plain[1] << 8) | (plain[2] << 16) | (plain[3] << 24));
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ciout:
1028c2ecf20Sopenharmony_ci	kfree(plain);
1038c2ecf20Sopenharmony_ci	return code;
1048c2ecf20Sopenharmony_ci}
105