Add rxgk_packet.c
[openafs.git] / src / rxgk / rxgk_packet.c
1 /* rxgk/rxgk_packet.c - packet-manipulating routines for rxgk */
2 /*
3  * Copyright (C) 2013, 2014 by the Massachusetts Institute of Technology.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  *   notice, this list of conditions and the following disclaimer.
12  *
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
16  *   distribution.
17  *
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.
30  */
31
32 /**
33  * @file
34  * Routines to encrypt or checksum packets, and perform the reverse
35  * decryption and checksum verification operations.
36  */
37
38 #include <afsconfig.h>
39 #include <afs/param.h>
40 #include <afs/stds.h>
41
42 #include <roken.h>
43
44 #include <rx/rx.h>
45 #include <rx/rx_packet.h>
46 #include <rx/rxgk.h>
47 #ifdef KERNEL
48 # include "afs/sysincludes.h"
49 # include "afsincludes.h"
50 #else
51 # include <errno.h>
52 #endif
53
54 #include "rxgk_private.h"
55
56 /**
57  * Fill in an rxgk_header structure from a packet
58  *
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.
62  *
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.
67  */
68 static void
69 populate_header(struct rxgk_header *header, struct rx_packet *apacket,
70                 afs_int32 index, afs_uint32 length)
71 {
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);
78 }
79
80 /**
81  * Verify the MIC on a packet
82  *
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.
86  *
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.
92  */
93 int
94 rxgk_check_mic_packet(rxgk_key tk, afs_int32 keyusage,
95                       struct rx_connection *aconn, struct rx_packet *apacket)
96 {
97     struct rx_opaque plain = RX_EMPTY_OPAQUE, mic = RX_EMPTY_OPAQUE;
98     struct rxgk_header *header;
99     afs_int32 ret;
100     afs_uint32 len;
101     size_t miclen;
102
103     miclen = rx_GetSecurityHeaderSize(aconn);
104     if (miclen == 0) {
105         ret = RXGK_INCONSISTENCY;
106         goto done;
107     }
108     if (rx_GetDataSize(apacket) < miclen) {
109         ret = RXGK_PACKETSHORT;
110         goto done;
111     }
112     len = rx_GetDataSize(apacket) - miclen;
113     ret = rx_opaque_alloc(&plain, sizeof(*header) + len);
114     if (ret != 0)
115         goto done;
116     header = plain.val;
117     ret = rx_opaque_alloc(&mic, miclen);
118     if (ret != 0)
119         goto done;
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));
124
125     /* The actual crypto call */
126     ret = rxgk_check_mic_in_key(tk, keyusage, &plain, &mic);
127
128     /*
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.
133      */
134     rx_SetDataSize(apacket, len);
135
136  done:
137     rx_opaque_freeContents(&plain);
138     rx_opaque_freeContents(&mic);
139     return ret;
140 }
141
142 /**
143  * Decrypt a packet to plaintext
144  *
145  * Take an encrypted packet and decrypt it with the specified key and
146  * key usage.  Put the plaintext back in the packet.
147  *
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.
153  */
154 int
155 rxgk_decrypt_packet(rxgk_key tk, afs_int32 keyusage,
156                     struct rx_connection *aconn, struct rx_packet *apacket)
157 {
158     struct rx_opaque plain = RX_EMPTY_OPAQUE, crypt = RX_EMPTY_OPAQUE;
159     struct rxgk_header *header = NULL, *cryptheader;
160     afs_int32 ret;
161     afs_uint32 len;
162
163     len = rx_GetDataSize(apacket);
164
165     if (rx_GetSecurityHeaderSize(aconn) != sizeof(*header)) {
166         ret = RXGK_INCONSISTENCY;
167         goto done;
168     }
169
170     header = rxi_Alloc(sizeof(*header));
171     if (header == NULL) {
172         ret = ENOMEM;
173         goto done;
174     }
175     ret = rx_opaque_alloc(&crypt, len);
176     if (ret != 0)
177         goto done;
178     rx_packetread(apacket, 0, len, crypt.val);
179
180     /* The actual decryption */
181     ret = rxgk_decrypt_in_key(tk, keyusage, &crypt, &plain);
182     if (ret != 0)
183         goto done;
184
185     if (plain.len < sizeof(*cryptheader)) {
186         /*
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
189          * clearly wrong.
190          */
191         ret = RXGK_DATA_LEN;
192         goto done;
193     }
194     cryptheader = plain.val;
195
196     /*
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.
205      */
206     if (ntohl(cryptheader->length) > plain.len - sizeof(*cryptheader)) {
207         ret = RXGK_DATA_LEN;
208         goto done;
209     }
210
211     populate_header(header, apacket, rx_SecurityClassOf(aconn),
212                     ntohl(cryptheader->length));
213
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));
217     if (ret != 0) {
218         ret = RXGK_SEALED_INCON;
219         goto done;
220     }
221
222     len = ntohl(cryptheader->length) + sizeof(*header);
223     if (len > 0xffffu) {
224         ret = RXGK_DATA_LEN;
225         goto done;
226     }
227
228     /*
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).
234      */
235     rx_packetwrite(apacket, 0, len, plain.val);
236     rx_SetDataSize(apacket, ntohl(cryptheader->length));
237
238  done:
239     rx_opaque_freeContents(&plain);
240     rx_opaque_freeContents(&crypt);
241     rxi_Free(header, sizeof(*header));
242     return ret;
243 }
244
245 /**
246  * Compute the MIC of a packet using a given key and key usage
247  *
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.
251  *
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.
257  */
258 int
259 rxgk_mic_packet(rxgk_key tk, afs_int32 keyusage, struct rx_connection *aconn,
260                 struct rx_packet *apacket)
261 {
262     struct rx_opaque plain = RX_EMPTY_OPAQUE, mic = RX_EMPTY_OPAQUE;
263     struct rxgk_header *header;
264     afs_uint32 len, miclen;
265     int ret;
266
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);
271     if (ret != 0)
272         goto done;
273     header = plain.val;
274     populate_header(header, apacket, rx_SecurityClassOf(aconn), len);
275     rx_packetread(apacket, miclen, len,
276                   (unsigned char *)plain.val + sizeof(*header));
277
278     /* The actual mic */
279     ret = rxgk_mic_in_key(tk, keyusage, &plain, &mic);
280     if (ret != 0)
281         goto done;
282
283     if (mic.len != miclen) {
284         ret = RXGK_INCONSISTENCY;
285         goto done;
286     }
287
288     rx_packetwrite(apacket, 0, mic.len, mic.val);
289     rx_SetDataSize(apacket, mic.len + len);
290
291  done:
292     rx_opaque_freeContents(&plain);
293     rx_opaque_freeContents(&mic);
294     return ret;
295 }
296
297 /**
298  * Encrypt a packet using a given key and key usage
299  *
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.
303  *
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.
309  */
310 int
311 rxgk_enc_packet(rxgk_key tk, afs_int32 keyusage, struct rx_connection *aconn,
312                 struct rx_packet *apacket)
313 {
314     struct rx_opaque plain = RX_EMPTY_OPAQUE, crypt = RX_EMPTY_OPAQUE;
315     struct rxgk_header *header;
316     afs_int32 ret;
317     afs_uint32 len;
318
319     len = rx_GetDataSize(apacket);
320     if (rx_GetSecurityHeaderSize(aconn) != sizeof(*header)) {
321         ret = RXGK_INCONSISTENCY;
322         goto done;
323     }
324     ret = rx_opaque_alloc(&plain, sizeof(*header) + len);
325     if (ret != 0)
326         goto done;
327     header = plain.val;
328     populate_header(header, apacket, rx_SecurityClassOf(aconn), len);
329     rx_packetread(apacket, sizeof(*header), len,
330                   (unsigned char *)plain.val + sizeof(*header));
331
332     /* The actual encryption */
333     ret = rxgk_encrypt_in_key(tk, keyusage, &plain, &crypt);
334     if (ret != 0)
335         goto done;
336     if (crypt.len > 0xffffu) {
337         ret = RXGK_DATA_LEN;
338         goto done;
339     }
340
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);
346
347  done:
348     rx_opaque_freeContents(&plain);
349     rx_opaque_freeContents(&crypt);
350     return ret;
351 }