cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

gss_krb5_unseal.c (6858B)


      1/*
      2 *  linux/net/sunrpc/gss_krb5_unseal.c
      3 *
      4 *  Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/k5unseal.c
      5 *
      6 *  Copyright (c) 2000-2008 The Regents of the University of Michigan.
      7 *  All rights reserved.
      8 *
      9 *  Andy Adamson   <andros@umich.edu>
     10 */
     11
     12/*
     13 * Copyright 1993 by OpenVision Technologies, Inc.
     14 *
     15 * Permission to use, copy, modify, distribute, and sell this software
     16 * and its documentation for any purpose is hereby granted without fee,
     17 * provided that the above copyright notice appears in all copies and
     18 * that both that copyright notice and this permission notice appear in
     19 * supporting documentation, and that the name of OpenVision not be used
     20 * in advertising or publicity pertaining to distribution of the software
     21 * without specific, written prior permission. OpenVision makes no
     22 * representations about the suitability of this software for any
     23 * purpose.  It is provided "as is" without express or implied warranty.
     24 *
     25 * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     26 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     27 * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     28 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
     29 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
     30 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     31 * PERFORMANCE OF THIS SOFTWARE.
     32 */
     33
     34/*
     35 * Copyright (C) 1998 by the FundsXpress, INC.
     36 *
     37 * All rights reserved.
     38 *
     39 * Export of this software from the United States of America may require
     40 * a specific license from the United States Government.  It is the
     41 * responsibility of any person or organization contemplating export to
     42 * obtain such a license before exporting.
     43 *
     44 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
     45 * distribute this software and its documentation for any purpose and
     46 * without fee is hereby granted, provided that the above copyright
     47 * notice appear in all copies and that both that copyright notice and
     48 * this permission notice appear in supporting documentation, and that
     49 * the name of FundsXpress. not be used in advertising or publicity pertaining
     50 * to distribution of the software without specific, written prior
     51 * permission.  FundsXpress makes no representations about the suitability of
     52 * this software for any purpose.  It is provided "as is" without express
     53 * or implied warranty.
     54 *
     55 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
     56 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
     57 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     58 */
     59
     60#include <linux/types.h>
     61#include <linux/jiffies.h>
     62#include <linux/sunrpc/gss_krb5.h>
     63#include <linux/crypto.h>
     64
     65#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
     66# define RPCDBG_FACILITY        RPCDBG_AUTH
     67#endif
     68
     69
     70/* read_token is a mic token, and message_buffer is the data that the mic was
     71 * supposedly taken over. */
     72
     73static u32
     74gss_verify_mic_v1(struct krb5_ctx *ctx,
     75		struct xdr_buf *message_buffer, struct xdr_netobj *read_token)
     76{
     77	int			signalg;
     78	int			sealalg;
     79	char			cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
     80	struct xdr_netobj	md5cksum = {.len = sizeof(cksumdata),
     81					    .data = cksumdata};
     82	s32			now;
     83	int			direction;
     84	u32			seqnum;
     85	unsigned char		*ptr = (unsigned char *)read_token->data;
     86	int			bodysize;
     87	u8			*cksumkey;
     88
     89	dprintk("RPC:       krb5_read_token\n");
     90
     91	if (g_verify_token_header(&ctx->mech_used, &bodysize, &ptr,
     92					read_token->len))
     93		return GSS_S_DEFECTIVE_TOKEN;
     94
     95	if ((ptr[0] != ((KG_TOK_MIC_MSG >> 8) & 0xff)) ||
     96	    (ptr[1] !=  (KG_TOK_MIC_MSG & 0xff)))
     97		return GSS_S_DEFECTIVE_TOKEN;
     98
     99	/* XXX sanity-check bodysize?? */
    100
    101	signalg = ptr[2] + (ptr[3] << 8);
    102	if (signalg != ctx->gk5e->signalg)
    103		return GSS_S_DEFECTIVE_TOKEN;
    104
    105	sealalg = ptr[4] + (ptr[5] << 8);
    106	if (sealalg != SEAL_ALG_NONE)
    107		return GSS_S_DEFECTIVE_TOKEN;
    108
    109	if ((ptr[6] != 0xff) || (ptr[7] != 0xff))
    110		return GSS_S_DEFECTIVE_TOKEN;
    111
    112	if (ctx->gk5e->keyed_cksum)
    113		cksumkey = ctx->cksum;
    114	else
    115		cksumkey = NULL;
    116
    117	if (make_checksum(ctx, ptr, 8, message_buffer, 0,
    118			  cksumkey, KG_USAGE_SIGN, &md5cksum))
    119		return GSS_S_FAILURE;
    120
    121	if (memcmp(md5cksum.data, ptr + GSS_KRB5_TOK_HDR_LEN,
    122					ctx->gk5e->cksumlength))
    123		return GSS_S_BAD_SIG;
    124
    125	/* it got through unscathed.  Make sure the context is unexpired */
    126
    127	now = ktime_get_real_seconds();
    128
    129	if (now > ctx->endtime)
    130		return GSS_S_CONTEXT_EXPIRED;
    131
    132	/* do sequencing checks */
    133
    134	if (krb5_get_seq_num(ctx, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8,
    135			     &direction, &seqnum))
    136		return GSS_S_FAILURE;
    137
    138	if ((ctx->initiate && direction != 0xff) ||
    139	    (!ctx->initiate && direction != 0))
    140		return GSS_S_BAD_SIG;
    141
    142	return GSS_S_COMPLETE;
    143}
    144
    145static u32
    146gss_verify_mic_v2(struct krb5_ctx *ctx,
    147		struct xdr_buf *message_buffer, struct xdr_netobj *read_token)
    148{
    149	char cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
    150	struct xdr_netobj cksumobj = {.len = sizeof(cksumdata),
    151				      .data = cksumdata};
    152	time64_t now;
    153	u8 *ptr = read_token->data;
    154	u8 *cksumkey;
    155	u8 flags;
    156	int i;
    157	unsigned int cksum_usage;
    158	__be16 be16_ptr;
    159
    160	dprintk("RPC:       %s\n", __func__);
    161
    162	memcpy(&be16_ptr, (char *) ptr, 2);
    163	if (be16_to_cpu(be16_ptr) != KG2_TOK_MIC)
    164		return GSS_S_DEFECTIVE_TOKEN;
    165
    166	flags = ptr[2];
    167	if ((!ctx->initiate && (flags & KG2_TOKEN_FLAG_SENTBYACCEPTOR)) ||
    168	    (ctx->initiate && !(flags & KG2_TOKEN_FLAG_SENTBYACCEPTOR)))
    169		return GSS_S_BAD_SIG;
    170
    171	if (flags & KG2_TOKEN_FLAG_SEALED) {
    172		dprintk("%s: token has unexpected sealed flag\n", __func__);
    173		return GSS_S_FAILURE;
    174	}
    175
    176	for (i = 3; i < 8; i++)
    177		if (ptr[i] != 0xff)
    178			return GSS_S_DEFECTIVE_TOKEN;
    179
    180	if (ctx->initiate) {
    181		cksumkey = ctx->acceptor_sign;
    182		cksum_usage = KG_USAGE_ACCEPTOR_SIGN;
    183	} else {
    184		cksumkey = ctx->initiator_sign;
    185		cksum_usage = KG_USAGE_INITIATOR_SIGN;
    186	}
    187
    188	if (make_checksum_v2(ctx, ptr, GSS_KRB5_TOK_HDR_LEN, message_buffer, 0,
    189			     cksumkey, cksum_usage, &cksumobj))
    190		return GSS_S_FAILURE;
    191
    192	if (memcmp(cksumobj.data, ptr + GSS_KRB5_TOK_HDR_LEN,
    193				ctx->gk5e->cksumlength))
    194		return GSS_S_BAD_SIG;
    195
    196	/* it got through unscathed.  Make sure the context is unexpired */
    197	now = ktime_get_real_seconds();
    198	if (now > ctx->endtime)
    199		return GSS_S_CONTEXT_EXPIRED;
    200
    201	/*
    202	 * NOTE: the sequence number at ptr + 8 is skipped, rpcsec_gss
    203	 * doesn't want it checked; see page 6 of rfc 2203.
    204	 */
    205
    206	return GSS_S_COMPLETE;
    207}
    208
    209u32
    210gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
    211			struct xdr_buf *message_buffer,
    212			struct xdr_netobj *read_token)
    213{
    214	struct krb5_ctx *ctx = gss_ctx->internal_ctx_id;
    215
    216	switch (ctx->enctype) {
    217	default:
    218		BUG();
    219	case ENCTYPE_DES_CBC_RAW:
    220	case ENCTYPE_DES3_CBC_RAW:
    221		return gss_verify_mic_v1(ctx, message_buffer, read_token);
    222	case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
    223	case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
    224		return gss_verify_mic_v2(ctx, message_buffer, read_token);
    225	}
    226}