1 /* rxgk/rxgk_util.c - utility functions for RXGK use */
3 * Copyright (C) 2013, 2014 by the Massachusetts Institute of Technology.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29 * OF THE POSSIBILITY OF SUCH DAMAGE.
34 * Utility functions for RXGK use. Compute the security overhead for a
35 * connection at a given security level, and helpers for maintaining key
36 * version numbers for connections.
39 #include <afsconfig.h>
40 #include <afs/param.h>
44 #include <rx/rx_identity.h>
46 #include <rx/rx_packet.h>
47 #include <afs/rfc3961.h>
49 # include "afs/sysincludes.h"
50 # include "afsincludes.h"
55 #include "rxgk_private.h"
58 * Set the security header and trailer sizes on a connection
60 * Set the security header and trailer sizes on aconn to be consistent
61 * with the space needed for packet handling at the given security level
62 * using the given key (only its enctype/checksum type are relevant).
64 * @param[out] aconn The connection being modified.
65 * @param[in] level The security level of the connection.
66 * @param[in] k0 The master key for the connection.
67 * @return rxgk error codes.
70 rxgk_security_overhead(struct rx_connection *aconn, RXGK_Level level,
78 case RXGK_LEVEL_CLEAR:
81 ret = rxgk_mic_length(k0, &mlen);
84 rx_SetSecurityHeaderSize(aconn, mlen);
85 rx_SetSecurityMaxTrailerSize(aconn, 0);
87 case RXGK_LEVEL_CRYPT:
88 ret = rxgk_cipher_expansion(k0, &elen);
91 rx_SetSecurityHeaderSize(aconn, sizeof(struct rxgk_header));
92 rx_SetSecurityMaxTrailerSize(aconn, elen);
95 return RXGK_INCONSISTENCY;
100 * Compute the full 32-bit kvno of a connection
102 * Given the 16-bit wire kvno and the local state, return the actual kvno which
103 * should be used for key derivation. All values are in host byte order.
104 * Understanding how we derive a 32-bit kvno from a 16-bit value requires some
107 * After an rxgk conn is set up, our peer informs us of kvno changes by sending
108 * the lowest 16 bits of its kvno. The real kvno being used is a 32-bit value,
109 * but the peer cannot change the kvno arbitrarily; the protocol spec only
110 * allows a peer to change the kvno by incrementing or decrementing it by 1. So
111 * if we know the current 32-bit kvno ('local'), and we know the advertised
112 * lower 16 bits of the new kvno ('wire'), we can calculate the new 32-bit kvno
115 * @param[in] wire The 16-bit kvno from the received packet.
116 * @param[in] local The 32-bit kvno from the local connection state.
117 * @param[out] real The kvno to be used to process this packet.
118 * @return rxgk error codes.
121 rxgk_key_number(afs_uint16 wire, afs_uint32 local, afs_uint32 *real)
123 afs_uint16 lres, diff;
125 lres = local % (1u << 16);
126 diff = (afs_uint16)(wire - lres);
130 } else if (diff == 1) {
131 /* Our peer is using a kvno 1 higher than 'local' */
132 if (local == MAX_AFS_UINT32)
133 return RXGK_INCONSISTENCY;
136 } else if (diff == (afs_uint16)0xffffu) {
137 /* Our peer is using a kvno 1 lower than 'local' */
139 return RXGK_INCONSISTENCY;
143 return RXGK_BADKEYNO;