1 /* rxgk/rxgk_packet.c - packet-manipulating routines for rxgk */
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 * Routines to encrypt or checksum packets, and perform the reverse
35 * decryption and checksum verification operations.
38 #include <afsconfig.h>
39 #include <afs/param.h>
45 #include <rx/rx_packet.h>
48 # include "afs/sysincludes.h"
49 # include "afsincludes.h"
54 #include "rxgk_private.h"
57 * Fill in an rxgk_header structure from a packet
59 * Fill in the elements of the rxgk_header structure, in network byte order,
60 * using information from the packet structure and the supplied values for
61 * the security index and data length.
63 * @param[out] header The header structure to be populated.
64 * @param[in] apacket The packet from which to pull connection information.
65 * @param[in] index The security index of the connection.
66 * @param[in] length The (plaintext) data length of the packet.
69 populate_header(struct rxgk_header *header, struct rx_packet *apacket,
70 afs_int32 index, afs_uint32 length)
72 header->epoch = htonl(apacket->header.epoch);
73 header->cid = htonl(apacket->header.cid);
74 header->callNumber = htonl(apacket->header.callNumber);
75 header->seq = htonl(apacket->header.seq);
76 header->index = htonl(index);
77 header->length = htonl(length);
81 * Verify the MIC on a packet
83 * Take a packet, extract the MIC and data payload, prefix the data with the
84 * rxgk pseudoheader, and verify the mic of that assembly. The plaintext
85 * data remains at its present location in the packet.
87 * @param[in] tk The transport key to be used.
88 * @param[in] keyusage The key usage value used to generate the MIC.
89 * @param[in] aconn The rx connection on which the packet was received.
90 * @param[in,out] apacket The packet to be processed.
91 * @return rxgk error codes. An error is returned if the MIC is invalid.
94 rxgk_check_mic_packet(rxgk_key tk, afs_int32 keyusage,
95 struct rx_connection *aconn, struct rx_packet *apacket)
97 struct rx_opaque plain = RX_EMPTY_OPAQUE, mic = RX_EMPTY_OPAQUE;
98 struct rxgk_header *header;
103 miclen = rx_GetSecurityHeaderSize(aconn);
105 ret = RXGK_INCONSISTENCY;
108 if (rx_GetDataSize(apacket) < miclen) {
109 ret = RXGK_PACKETSHORT;
112 len = rx_GetDataSize(apacket) - miclen;
113 ret = rx_opaque_alloc(&plain, sizeof(*header) + len);
117 ret = rx_opaque_alloc(&mic, miclen);
120 populate_header(header, apacket, rx_SecurityClassOf(aconn), len);
121 rx_packetread(apacket, 0, miclen, mic.val);
122 rx_packetread(apacket, miclen, len,
123 (unsigned char *)plain.val + sizeof(*header));
125 /* The actual crypto call */
126 ret = rxgk_check_mic_in_key(tk, keyusage, &plain, &mic);
129 * We need to tell Rx how many bytes of payload there are in the packet
130 * before returning. We haven't touched the payload, so the amount of
131 * payload is just the original data size of packet, minus our overhead for
132 * the mic. This is just 'len', calculated above.
134 rx_SetDataSize(apacket, len);
137 rx_opaque_freeContents(&plain);
138 rx_opaque_freeContents(&mic);
143 * Decrypt a packet to plaintext
145 * Take an encrypted packet and decrypt it with the specified key and
146 * key usage. Put the plaintext back in the packet.
148 * @param[in] tk The transport key to use.
149 * @param[in] keyusage The key usage used to encrypt the packet.
150 * @param[in] aconn The rx connection on which the packet was received.
151 * @param[in,out] apacket The packet being decrypted.
152 * @return rxgk and system error codes.
155 rxgk_decrypt_packet(rxgk_key tk, afs_int32 keyusage,
156 struct rx_connection *aconn, struct rx_packet *apacket)
158 struct rx_opaque plain = RX_EMPTY_OPAQUE, crypt = RX_EMPTY_OPAQUE;
159 struct rxgk_header *header = NULL, *cryptheader;
163 len = rx_GetDataSize(apacket);
165 if (rx_GetSecurityHeaderSize(aconn) != sizeof(*header)) {
166 ret = RXGK_INCONSISTENCY;
170 header = rxi_Alloc(sizeof(*header));
171 if (header == NULL) {
175 ret = rx_opaque_alloc(&crypt, len);
178 rx_packetread(apacket, 0, len, crypt.val);
180 /* The actual decryption */
181 ret = rxgk_decrypt_in_key(tk, keyusage, &crypt, &plain);
185 if (plain.len < sizeof(*cryptheader)) {
187 * Our decrypted contents must have an rxgk_header at the start. If we
188 * don't even have enough bytes for an rxgk_header, something is
194 cryptheader = plain.val;
197 * cryptheader->length indicates the length of the decrypted plaintext of
198 * this packet. We must rely on this value, and we cannot calculate it
199 * ourselves from e.g. plain.len, since the encryption routines may have
200 * padded the plaintext. However, we also must not blindly trust the
201 * cryptheader->length value, since if it is set to larger than the actual
202 * plaintext length, we could read beyond the end of the buffer in
203 * plain.val. So check that cryptheader->length is not larger than the max
204 * size of the plaintext in our decrypted buffer.
206 if (ntohl(cryptheader->length) > plain.len - sizeof(*cryptheader)) {
211 populate_header(header, apacket, rx_SecurityClassOf(aconn),
212 ntohl(cryptheader->length));
214 /* Verify the encrypted header. Note the constant-time memcmp here, since
215 * this is a security-sensitive comparison. */
216 ret = ct_memcmp(header, cryptheader, sizeof(*header));
218 ret = RXGK_SEALED_INCON;
222 len = ntohl(cryptheader->length) + sizeof(*header);
229 * Now, write the plain data back to the packet. Note that we write back
230 * the decrypted packet payload, and the rxgk_header contents. We don't
231 * really need the rxgk_header in there anymore, but the Rx API does not
232 * let us skip it (Rx will skip the first N bytes when reading the packet
233 * payload, where N is our security header size).
235 rx_packetwrite(apacket, 0, len, plain.val);
236 rx_SetDataSize(apacket, ntohl(cryptheader->length));
239 rx_opaque_freeContents(&plain);
240 rx_opaque_freeContents(&crypt);
241 rxi_Free(header, sizeof(*header));
246 * Compute the MIC of a packet using a given key and key usage
248 * Take a packet, prefix it with the rxgk pseudoheader, MIC the whole
249 * thing with specified key and key usage, then insert the mic into the
250 * packet payload before the actual data.
252 * @param[in] tk The transport key to use.
253 * @param[in] keyusage The key usage to use for the MIC.
254 * @param[in] aconn The rx connection on which the packet will be sent.
255 * @param[in,out] apacket The packet whose MIC is being calculated.
256 * @return rxgk error codes.
259 rxgk_mic_packet(rxgk_key tk, afs_int32 keyusage, struct rx_connection *aconn,
260 struct rx_packet *apacket)
262 struct rx_opaque plain = RX_EMPTY_OPAQUE, mic = RX_EMPTY_OPAQUE;
263 struct rxgk_header *header;
264 afs_uint32 len, miclen;
267 /* This 'len' does NOT include our overhead for the mic */
268 len = rx_GetDataSize(apacket);
269 miclen = rx_GetSecurityHeaderSize(aconn);
270 ret = rx_opaque_alloc(&plain, sizeof(*header) + len);
274 populate_header(header, apacket, rx_SecurityClassOf(aconn), len);
275 rx_packetread(apacket, miclen, len,
276 (unsigned char *)plain.val + sizeof(*header));
279 ret = rxgk_mic_in_key(tk, keyusage, &plain, &mic);
283 if (mic.len != miclen) {
284 ret = RXGK_INCONSISTENCY;
288 rx_packetwrite(apacket, 0, mic.len, mic.val);
289 rx_SetDataSize(apacket, mic.len + len);
292 rx_opaque_freeContents(&plain);
293 rx_opaque_freeContents(&mic);
298 * Encrypt a packet using a given key and key usage
300 * Take a packet, prefix it with the rxgk pseudoheader, encrypt the whole
301 * thing with specified key and key usage, then rewrite the packet payload
302 * to be the encrypted version.
304 * @param[in] tk The transport key to use.
305 * @param[in] keyusage The key usage for the encryption.
306 * @param[in] aconn The rx connection on which the packet will be sent.
307 * @param[in,out] apacket The packet being encrypted.
308 * @return rxgk error codes.
311 rxgk_enc_packet(rxgk_key tk, afs_int32 keyusage, struct rx_connection *aconn,
312 struct rx_packet *apacket)
314 struct rx_opaque plain = RX_EMPTY_OPAQUE, crypt = RX_EMPTY_OPAQUE;
315 struct rxgk_header *header;
319 len = rx_GetDataSize(apacket);
320 if (rx_GetSecurityHeaderSize(aconn) != sizeof(*header)) {
321 ret = RXGK_INCONSISTENCY;
324 ret = rx_opaque_alloc(&plain, sizeof(*header) + len);
328 populate_header(header, apacket, rx_SecurityClassOf(aconn), len);
329 rx_packetread(apacket, sizeof(*header), len,
330 (unsigned char *)plain.val + sizeof(*header));
332 /* The actual encryption */
333 ret = rxgk_encrypt_in_key(tk, keyusage, &plain, &crypt);
336 if (crypt.len > 0xffffu) {
341 /* Now, put the data back. */
342 if (crypt.len > plain.len)
343 rxi_RoundUpPacket(apacket, crypt.len - plain.len);
344 rx_packetwrite(apacket, 0, crypt.len, crypt.val);
345 rx_SetDataSize(apacket, crypt.len);
348 rx_opaque_freeContents(&plain);
349 rx_opaque_freeContents(&crypt);