1/*
2 * ngtcp2
3 *
4 * Copyright (c) 2017 ngtcp2 contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25#ifndef NGTCP2_PPE_H
26#define NGTCP2_PPE_H
27
28#ifdef HAVE_CONFIG_H
29#  include <config.h>
30#endif /* HAVE_CONFIG_H */
31
32#include <ngtcp2/ngtcp2.h>
33
34#include "ngtcp2_pkt.h"
35#include "ngtcp2_buf.h"
36#include "ngtcp2_crypto.h"
37
38/*
39 * ngtcp2_ppe is the Protected Packet Encoder.
40 */
41typedef struct ngtcp2_ppe {
42  ngtcp2_buf buf;
43  ngtcp2_crypto_cc *cc;
44  /* hdlen is the number of bytes for packet header written in buf. */
45  size_t hdlen;
46  /* len_offset is the offset to Length field. */
47  size_t len_offset;
48  /* pkt_num_offset is the offset to packet number field. */
49  size_t pkt_num_offset;
50  /* pkt_numlen is the number of bytes used to encode a packet
51     number */
52  size_t pkt_numlen;
53  /* sample_offset is the offset to sample for packet number
54     encryption. */
55  size_t sample_offset;
56  /* pkt_num is the packet number written in buf. */
57  int64_t pkt_num;
58  /* nonce is the buffer to store nonce.  It should be equal or longer
59     than then length of IV. */
60  uint8_t nonce[32];
61} ngtcp2_ppe;
62
63/*
64 * ngtcp2_ppe_init initializes |ppe| with the given buffer.
65 */
66void ngtcp2_ppe_init(ngtcp2_ppe *ppe, uint8_t *out, size_t outlen,
67                     ngtcp2_crypto_cc *cc);
68
69/*
70 * ngtcp2_ppe_encode_hd encodes |hd|.
71 *
72 * This function returns 0 if it succeeds, or one of the following
73 * negative error codes:
74 *
75 * NGTCP2_ERR_NOBUF
76 *     The buffer is too small.
77 */
78int ngtcp2_ppe_encode_hd(ngtcp2_ppe *ppe, const ngtcp2_pkt_hd *hd);
79
80/*
81 * ngtcp2_ppe_encode_frame encodes |fr|.
82 *
83 * This function returns 0 if it succeeds, or one of the following
84 * negative error codes:
85 *
86 * NGTCP2_ERR_NOBUF
87 *     The buffer is too small.
88 */
89int ngtcp2_ppe_encode_frame(ngtcp2_ppe *ppe, ngtcp2_frame *fr);
90
91/*
92 * ngtcp2_ppe_final encrypts QUIC packet payload.  If |**ppkt| is not
93 * NULL, the pointer to the packet is assigned to it.
94 *
95 * This function returns the length of QUIC packet, including header,
96 * and payload if it succeeds, or one of the following negative error
97 * codes:
98 *
99 * NGTCP2_ERR_CALLBACK_FAILURE
100 *     User-defined callback function failed.
101 */
102ngtcp2_ssize ngtcp2_ppe_final(ngtcp2_ppe *ppe, const uint8_t **ppkt);
103
104/*
105 * ngtcp2_ppe_left returns the number of bytes left to write
106 * additional frames.  This does not count AEAD overhead.
107 */
108size_t ngtcp2_ppe_left(ngtcp2_ppe *ppe);
109
110/*
111 * ngtcp2_ppe_pktlen returns the provisional packet length.  It
112 * includes AEAD overhead.
113 */
114size_t ngtcp2_ppe_pktlen(ngtcp2_ppe *ppe);
115
116/**
117 * @function
118 *
119 * `ngtcp2_ppe_padding` encodes PADDING frames to the end of the
120 * buffer.  This function returns the number of bytes padded.
121 */
122size_t ngtcp2_ppe_padding(ngtcp2_ppe *ppe);
123
124/*
125 * ngtcp2_ppe_padding_hp_sample adds PADDING frame if the current
126 * payload does not have enough space for header protection sample.
127 * This function should be called just before calling
128 * ngtcp2_ppe_final().
129 *
130 * This function returns the number of bytes added as padding.
131 */
132size_t ngtcp2_ppe_padding_hp_sample(ngtcp2_ppe *ppe);
133
134/*
135 * ngtcp2_ppe_padding_size adds PADDING frame so that the size of QUIC
136 * packet is at least |n| bytes long.  If it is unable to add PADDING
137 * in that way, this function still adds PADDING frame as much as
138 * possible.  This function should be called just before calling
139 * ngtcp2_ppe_final().  For Short packet, this function should be
140 * called instead of ngtcp2_ppe_padding_hp_sample.
141 *
142 * This function returns the number of bytes added as padding.
143 */
144size_t ngtcp2_ppe_padding_size(ngtcp2_ppe *ppe, size_t n);
145
146/*
147 * ngtcp2_ppe_ensure_hp_sample returns nonzero if the buffer has
148 * enough space for header protection sample.  This should be called
149 * right after packet header is written.
150 */
151int ngtcp2_ppe_ensure_hp_sample(ngtcp2_ppe *ppe);
152
153#endif /* NGTCP2_PPE_H */
154