blob: 3adcd8d240ca06b8dc42eed55066d417f55c6496 [file] [log] [blame]
Alexandre Lision51140e12013-12-02 10:54:09 -05001/*
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002 Copyright (C) 2011 - 2012 Werner Dittmann
3
Alexandre Lision51140e12013-12-02 10:54:09 -05004 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*/
18
Alexandre Lision51140e12013-12-02 10:54:09 -050019#ifndef CRYPTOCONTEXTCTRL_H
20#define CRYPTOCONTEXTCTRL_H
21
22/**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050023 * @file CryptoContextCtrl.h
24 * @brief The C++ SRTCP implementation
Alexandre Lision51140e12013-12-02 10:54:09 -050025 * @ingroup Z_SRTP
26 * @{
27 */
28
Alexandre Lision51140e12013-12-02 10:54:09 -050029class SrtpSymCrypto;
30
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050031/**
32 * The implementation for a SRTCP cryptographic context.
33 *
34 * This class holds data and provides functions that implement a
35 * cryptographic context for SRTCP, Refer to RFC 3711, chapter 3.2 for some
36 * more detailed information about the SRTCP cryptographic context.
37 *
38 * Each SRTCP cryptographic context maintains a RTCP source identified by
39 * its SSRC. Thus you can independently protect each source inside a RTP
40 * session.
41 *
42 * Key management mechanisms negotiate the parameters for the SRTCP
43 * cryptographic context, such as master key, key length, authentication
44 * length and so on. The key management mechanisms are not part of
45 * SRTCP. Refer to MIKEY (RFC 3880) or to Phil Zimmermann's ZRTP protocol
46 * (RFC6189). After key management negotiated the data the application
47 * can setup the SRTCP cryptographic context and enable SRTCP processing.
48 *
49 * @sa CryptoContext
50 *
51 * @author Werner Dittmann <Werner.Dittmann@t-online.de>
52 */
Alexandre Lision51140e12013-12-02 10:54:09 -050053class CryptoContextCtrl {
54 public:
55 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050056 * @brief Constructor for an active SRTCP cryptographic context.
Alexandre Lision51140e12013-12-02 10:54:09 -050057 *
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050058 * This constructor creates an active SRTCP cryptographic context were
59 * algorithms are enabled, keys are computed and so on. This SRTCP
60 * cryptographic context can protect a RTCP SSRC stream.
61 *
62 * See the notes in CryptoContext documentation regarding the handling
63 * of key data.
Alexandre Lision51140e12013-12-02 10:54:09 -050064 *
65 * @param ssrc
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050066 * The RTP SSRC that this SRTCP cryptographic context protects.
Alexandre Lision51140e12013-12-02 10:54:09 -050067 *
68 * @param ealg
69 * The encryption algorithm to use. Possible values are <code>
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050070 * SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8,
Alexandre Lision51140e12013-12-02 10:54:09 -050071 * </code>. See chapter 4.1.1 for AESCM (Counter mode) and 4.1.2
72 * for AES F8 mode.
73 *
74 * @param aalg
75 * The authentication algorithm to use. Possible values are <code>
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050076 * SrtpEncryptionNull, SrtpAuthenticationSha1Hmac, SrtpAuthenticationSkeinHmac
77 * </code>.
Alexandre Lision51140e12013-12-02 10:54:09 -050078 *
79 * @param masterKey
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050080 * Pointer to the master key for this SRTCP cryptographic context.
Alexandre Lision51140e12013-12-02 10:54:09 -050081 * Must point to <code>masterKeyLength</code> bytes. Refer to chapter
82 * 3.2.1 of the RFC about the role of the master key.
83 *
84 * @param masterKeyLength
85 * The length in bytes of the master key in bytes. The length must
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050086 * match the selected encryption algorithm. Because SRTCP uses AES
Alexandre Lision51140e12013-12-02 10:54:09 -050087 * based encryption only, then master key length may be 16 or 32
88 * bytes (128 or 256 bit master key)
89 *
90 * @param masterSalt
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050091 * SRTCP uses the master salt to computer the initialization vector
Alexandre Lision51140e12013-12-02 10:54:09 -050092 * that in turn is input to compute the session key, session
93 * authentication key and the session salt.
94 *
95 * @param masterSaltLength
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050096 * The length in bytes of the master salt data in bytes. SRTCP uses
Alexandre Lision51140e12013-12-02 10:54:09 -050097 * AES as encryption algorithm. AES encrypts 16 byte blocks
98 * (independent of the key length). According to RFC3711 the standard
99 * value for the master salt length should be 112 bit (14 bytes).
100 *
101 * @param ekeyl
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500102 * The length in bytes of the session encryption key that SRTCP shall
Alexandre Lision51140e12013-12-02 10:54:09 -0500103 * compute and use. Usually the same length as for the master key
104 * length. But you may use a different length as well. Be carefull
105 * that the key management mechanisms supports different key lengths.
106 *
107 * @param akeyl
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500108 * The length in bytes of the session authentication key. SRTCP
Alexandre Lision51140e12013-12-02 10:54:09 -0500109 * computes this key and uses it as input to the authentication
110 * algorithm.
111 * The standard value is 160 bits (20 bytes).
112 *
113 * @param skeyl
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500114 * The length in bytes of the session salt. SRTCP computes this salt
Alexandre Lision51140e12013-12-02 10:54:09 -0500115 * key and uses it as input during encryption. The length usually
116 * is the same as the master salt length.
117 *
118 * @param tagLength
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500119 * The length is bytes of the authentication tag that SRTCP appends
Alexandre Lision51140e12013-12-02 10:54:09 -0500120 * to the RTP packet. Refer to chapter 4.2. in the RFC 3711.
121 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500122 CryptoContextCtrl(uint32_t ssrc,
Alexandre Lision51140e12013-12-02 10:54:09 -0500123 const int32_t ealg,
124 const int32_t aalg,
125 uint8_t* masterKey,
126 int32_t masterKeyLength,
127 uint8_t* masterSalt,
128 int32_t masterSaltLength,
129 int32_t ekeyl,
130 int32_t akeyl,
131 int32_t skeyl,
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500132 int32_t tagLength);
133
Alexandre Lision51140e12013-12-02 10:54:09 -0500134 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500135 * @brief Destructor.
Alexandre Lision51140e12013-12-02 10:54:09 -0500136 *
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500137 * Cleans the SRTCP cryptographic context.
Alexandre Lision51140e12013-12-02 10:54:09 -0500138 */
139 ~CryptoContextCtrl();
140
141 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500142 * @brief Perform SRTCP encryption.
Alexandre Lision51140e12013-12-02 10:54:09 -0500143 *
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500144 * This method encrypts <em>and</em> decrypts SRTCP payload data. Plain
Alexandre Lision51140e12013-12-02 10:54:09 -0500145 * data gets encrypted, encrypted data get decrypted.
146 *
147 * @param rtp
148 * The RTP packet that contains the data to encrypt.
149 *
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500150 * @param len
151 * Length of the RTCP packet
152 *
Alexandre Lision51140e12013-12-02 10:54:09 -0500153 * @param index
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500154 * The 31 bit SRTCP packet index.
Alexandre Lision51140e12013-12-02 10:54:09 -0500155 *
156 * @param ssrc
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500157 * The RTCP SSRC data in <em>host</em> order.
Alexandre Lision51140e12013-12-02 10:54:09 -0500158 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500159 void srtcpEncrypt(uint8_t* rtp, int32_t len, uint32_t index, uint32_t ssrc);
Alexandre Lision51140e12013-12-02 10:54:09 -0500160
161 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500162 * @brief Compute the authentication tag.
Alexandre Lision51140e12013-12-02 10:54:09 -0500163 *
164 * Compute the authentication tag according the the paramters in the
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500165 * SRTCP Cryptograhic context.
Alexandre Lision51140e12013-12-02 10:54:09 -0500166 *
167 * @param rtp
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500168 * The RTCP packet that contains the data to authenticate.
Alexandre Lision51140e12013-12-02 10:54:09 -0500169 *
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500170 * @param len
171 * Length of the RTCP packet
172 *
173 * @param index
174 * The 31 bit SRTCP index.
Alexandre Lision51140e12013-12-02 10:54:09 -0500175 *
176 * @param tag
177 * Points to a buffer that hold the computed tag. This buffer must
178 * be able to hold <code>tagLength</code> bytes.
179 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500180 void srtcpAuthenticate(uint8_t* rtp, int32_t len, uint32_t index, uint8_t* tag);
Alexandre Lision51140e12013-12-02 10:54:09 -0500181
182 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500183 * @brief Perform key derivation according to SRTCP specification
Alexandre Lision51140e12013-12-02 10:54:09 -0500184 *
185 * This method computes the session key, session authentication key and the
186 * session salt key. This method must be called at least once after the
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500187 * SRTCP cryptograhic context was set up.
Alexandre Lision51140e12013-12-02 10:54:09 -0500188 *
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500189 * This method clears the key data once it was processed by the encryptions'
190 * set key functions.
191 *
Alexandre Lision51140e12013-12-02 10:54:09 -0500192 */
193 void deriveSrtcpKeys();
194
195 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500196 * @brief Check for packet replay.
Alexandre Lision51140e12013-12-02 10:54:09 -0500197 *
198 * The method check if a received packet is either to old or was already
199 * received.
200 *
201 * The method supports a 64 packet history relative the the given
202 * sequence number.
203 *
204 * @param newSeqNumber
205 * The sequence number of the received RTCP packet in host order.
206 *
207 * @return <code>true</code> if no replay, <code>false</code> if packet
208 * is too old ar was already received.
209 */
210 bool checkReplay(uint32_t newSeqNumber);
211
212 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500213 * @brief Update the SRTCP packet index.
Alexandre Lision51140e12013-12-02 10:54:09 -0500214 *
215 * Call this method after all checks were successful. See chapter
216 * 3.3.1 in the RFC when to update the ROC and ROC processing.
217 *
218 * @param newSeqNumber
219 * The sequence number of the received RTCP packet in host order.
220 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500221 void update(uint32_t newSeqNumber);
Alexandre Lision51140e12013-12-02 10:54:09 -0500222
223 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500224 * @brief Get the length of the SRTCP authentication tag in bytes.
Alexandre Lision51140e12013-12-02 10:54:09 -0500225 *
226 * @return the length of the authentication tag.
227 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500228 inline int32_t getTagLength() const { return tagLength; }
Alexandre Lision51140e12013-12-02 10:54:09 -0500229
230 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500231 * @brief Get the length of the MKI in bytes.
Alexandre Lision51140e12013-12-02 10:54:09 -0500232 *
233 * @return the length of the MKI.
234 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500235 inline int32_t getMkiLength() const { return mkiLength; }
Alexandre Lision51140e12013-12-02 10:54:09 -0500236
237 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500238 * @brief Get the SSRC of this SRTCP Cryptograhic context.
Alexandre Lision51140e12013-12-02 10:54:09 -0500239 *
240 * @return the SSRC.
241 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500242 inline uint32_t getSsrc() const { return ssrcCtx; }
Alexandre Lision51140e12013-12-02 10:54:09 -0500243
244 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500245 * @brief Get the SRTCP index field of this SRTCP Cryptograhic context.
Alexandre Lision51140e12013-12-02 10:54:09 -0500246 *
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500247 * @return the SRTCP.
248 */
249 uint32_t getSrtcpIndex() const { return srtcpIndex; }
250
251 /**
252 * @brief Set the SRTCP index field of this SRTCP Cryptograhic context.
Alexandre Lision51140e12013-12-02 10:54:09 -0500253 *
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500254 * @param index the new SRTCP index value.
255 *
256 */
257 void setSrtcpIndex(uint32_t index) { srtcpIndex = index; }
258
259 /**
260 * @brief Set the start (base) number to compute the PRF labels.
261 *
262 * Refer to RFC3711, chapters 4.3.1 and 4.3.2 about values for labels.
263 * CryptoContextCtrl computes the labes as follows:
264 *
265 * - labelBase + 0 -> encryption label
266 * - labelBase + 1 -> authentication label
267 * - labelBase + 2 -> salting key label
268 *
269 * The CryptoContextCtrl constructor initializes CryptoContextCtrl#labelBase
270 * with 3 to comply with RFC 3711 label values.
271 *
272 * Applications may set #labelBase to other values to use CryptoContextCtrl
273 * for other purposes.
274 */
275 void setLabelbase(uint8_t base) { labelBase = base; }
276
277 /**
278 * @brief Derive a new Crypto Context for use with a new SSRC
279 *
280 * This method returns a new CryptoContextCtrl initialized with the data
281 * of this crypto context. The application can use this CryptoContextCtrl
282 * instance to encrypt / decrypt a new stream (Synchronization source) inside
283 * one RTCP session.
284 *
285 * Before the application can use this crypto context it must call deriveSrtcpKeys().
Alexandre Lision51140e12013-12-02 10:54:09 -0500286 *
287 * @param ssrc
288 * The SSRC for this context
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500289 *
Alexandre Lision51140e12013-12-02 10:54:09 -0500290 * @return
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500291 * a new CryptoContextCtrl with all relevant data set.
Alexandre Lision51140e12013-12-02 10:54:09 -0500292 */
293 CryptoContextCtrl* newCryptoContextForSSRC(uint32_t ssrc);
294
295 private:
296
297 uint32_t ssrcCtx;
298 bool using_mki;
299 uint32_t mkiLength;
300 uint8_t* mki;
301
302 uint32_t s_l;
303
304 /* bitmask for replay check */
305 uint64_t replay_window;
306
307 uint8_t* master_key;
308 uint32_t master_key_length;
309 uint8_t* master_salt;
310 uint32_t master_salt_length;
311
312 /* Session Encryption, Authentication keys, Salt */
313 int32_t n_e;
314 uint8_t* k_e;
315 int32_t n_a;
316 uint8_t* k_a;
317 int32_t n_s;
318 uint8_t* k_s;
319
320 int32_t ealg;
321 int32_t aalg;
322 int32_t ekeyl;
323 int32_t akeyl;
324 int32_t skeyl;
325 int32_t tagLength;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500326 uint32_t srtcpIndex;
327 uint8_t labelBase;
Alexandre Lision51140e12013-12-02 10:54:09 -0500328
329 void* macCtx;
330
331 SrtpSymCrypto* cipher;
332 SrtpSymCrypto* f8Cipher;
333 };
334
335/**
336 * @}
337 */
338
339#endif
340