blob: 25c3a08fcc19a31b33309a807d36d9d584325379 [file] [log] [blame]
Alexandre Lision51140e12013-12-02 10:54:09 -05001/*
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002 Copyright (C) 2006 - 2012 Werner Dittmann
Alexandre Lision51140e12013-12-02 10:54:09 -05003
4 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 CRYPTOCONTEXT_H
20#define CRYPTOCONTEXT_H
21
22/**
23 * @file CryptoContext.h
24 * @brief The C++ SRTP implementation
25 * @ingroup Z_SRTP
26 * @{
27 */
28
29#define REPLAY_WINDOW_SIZE 64
30
31const int SrtpAuthenticationNull = 0;
32const int SrtpAuthenticationSha1Hmac = 1;
33const int SrtpAuthenticationSkeinHmac = 2;
34
35const int SrtpEncryptionNull = 0;
36const int SrtpEncryptionAESCM = 1;
37const int SrtpEncryptionAESF8 = 2;
38const int SrtpEncryptionTWOCM = 3;
39const int SrtpEncryptionTWOF8 = 4;
40
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050041// Check if included via CryptoContextCtrl.cpp - avoid double definitions
Alexandre Lision51140e12013-12-02 10:54:09 -050042#ifndef CRYPTOCONTEXTCTRL_H
43
44#include <stdint.h>
Alexandre Lision51140e12013-12-02 10:54:09 -050045
46class SrtpSymCrypto;
47
48/**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050049 * @brief Implementation for a SRTP cryptographic context.
Alexandre Lision51140e12013-12-02 10:54:09 -050050 *
51 * This class holds data and provides functions that implement a
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050052 * cryptographic context for SRTP. Refer to RFC 3711, chapter 3.2 for some
Alexandre Lision51140e12013-12-02 10:54:09 -050053 * more detailed information about the SRTP cryptographic context.
54 *
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050055 * Each SRTP cryptographic context uses a RTP source identified by
Alexandre Lision51140e12013-12-02 10:54:09 -050056 * its SSRC. Thus you can independently protect each source inside a RTP
57 * session.
58 *
59 * Key management mechanisms negotiate the parameters for the SRTP
60 * cryptographic context, such as master key, key length, authentication
61 * length and so on. The key management mechanisms are not part of
62 * SRTP. Refer to MIKEY (RFC 3880) or to Phil Zimmermann's ZRTP protocol
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050063 * (RFC6189). After key management negotiated the data the application can
64 * setup the SRTP cryptographic context and enable SRTP processing.
Alexandre Lision51140e12013-12-02 10:54:09 -050065 *
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050066 * This SRTP context implementation supports RTP only.
Alexandre Lision51140e12013-12-02 10:54:09 -050067 *
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050068 * A short eample how to setup a SRTP CryptoContext:
69 @verbatim
70
71 // First some key and salt data - this data is just for demo purposes
72 uint8 masterKey[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
73 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
74
75 uint8 masterSalt[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
76 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d };
77
78 ...
79
80 CryptoContext* cryptoCtxSend =
81 new CryptoContext(0xfeedbacc,
82 0, // roc,
83 0L, // keyderivation rate << 48,
84 SrtpEncryptionAESCM, // encryption algo
85 SrtpAuthenticationSha1Hmac, // authtication algo
86 masterKey, // Master Key data
87 128 / 8, // Master Key length in bytes
88 masterSalt, // Master Salt data
89 112 / 8, // Master Salt length in bytes
90 128 / 8, // encryption keylength in bytes
91 160 / 8, // authentication key length in bytes (SHA1)
92 112 / 8, // session salt length in bytes
93 80 / 8); // authentication tag length in bytes
94
95 cryptoCtxSend->deriveSrtpKeys(0);
96
97 ....
98
99 // To protect a RTP packet
100 // buffer: pointer to the RTP packet, length of the RTP data, newLength is a
101 // pointer to a size_t that gets the updated length.
102 bool rc = SrtpHandler::protect(cryptoCtxSend, buffer, length, newLength);
103
104 // To unprotect a SRTP packet:
105 // buffer: pointer to the RTP packet, length of the SRTP data, newLength is a
106 // pointer to a size_t that gets the updated length.
107 int32_t rc = SrtpHandler::unprotect(cryptoCtxRecv, buffer, length, newLength);
108
109 @endverbatim
110 *
111 * @note You need two CryptoContext instances - one for the sending channel the
112 * other one for the receiving channel.
113 *
114 * Before an appliction can use a CryptoContext it must call the key derivation
115 * function deriveSrtpKeys() first. Only then this SRTP cryptographic context is ready
116 * to protect or unprotect a RTP SSRC stream.
117 *
118 * Together with the newCryptoContextForSSRC() function an application can prepare a
119 * CryptoContext and save it as template. Once it needs a new CryptoContext, say
120 * for a new SSRC, it calls newCryptoContextForSSRC() on the saved context to get an
121 * initialized copy and then call deriveSrtpKeys() to compute and process the keys.
122 *
123 * @note A saved, pre-initialized template contains the non-processed keys. Only
124 * the method deriveSrtpKeys() processes the keys and cleares them. Thus don't store
125 * CryptoContext templates if the application cannot protect the templates against
126 * reading from other possibly rogue applications.
127 *
128 * @sa SrtpHandler
129 *
Alexandre Lision51140e12013-12-02 10:54:09 -0500130 * @author Werner Dittmann <Werner.Dittmann@t-online.de>
131 */
Alexandre Lision51140e12013-12-02 10:54:09 -0500132class CryptoContext {
133public:
134 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500135 * @brief Constructor for an active SRTP cryptographic context.
Alexandre Lision51140e12013-12-02 10:54:09 -0500136 *
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500137 * This constructor creates an pre-initialized SRTP cryptographic context were
138 * algorithms are allocated, keys are stored and so on. An application can
139 * call newCryptoContextForSSRC() to get a full copy of this pre-initialized
140 * CryptoContext.
141 *
Alexandre Lision51140e12013-12-02 10:54:09 -0500142 *
143 * @param ssrc
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500144 * The RTP SSRC that this SRTP cryptographic context belongs to.
Alexandre Lision51140e12013-12-02 10:54:09 -0500145 *
146 * @param roc
147 * The initial Roll-Over-Counter according to RFC 3711. These are the
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500148 * upper 32 bit of the overall 48 bit SRTP packet index. Usually set to zero.
149 * Refer to chapter 3.2.1 of the RFC.
Alexandre Lision51140e12013-12-02 10:54:09 -0500150 *
151 * @param keyDerivRate
152 * The key derivation rate defines when to recompute the SRTP session
153 * keys. Refer to chapter 4.3.1 in the RFC.
154 *
155 * @param ealg
156 * The encryption algorithm to use. Possible values are <code>
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500157 * SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8,
158 * SrtpEncryptionTWOCM, SrtpEncryptionTWOF8</code>. See chapter 4.1.1
159 * for AESCM (Counter mode) and 4.1.2 for AES F8 mode.
Alexandre Lision51140e12013-12-02 10:54:09 -0500160 *
161 * @param aalg
162 * The authentication algorithm to use. Possible values are <code>
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500163 * SrtpEncryptionNull, SrtpAuthenticationSha1Hmac, SrtpAuthenticationSkeinHmac
164 * </code>.
Alexandre Lision51140e12013-12-02 10:54:09 -0500165 *
166 * @param masterKey
167 * Pointer to the master key for this SRTP cryptographic context.
168 * Must point to <code>masterKeyLength</code> bytes. Refer to chapter
169 * 3.2.1 of the RFC about the role of the master key.
170 *
171 * @param masterKeyLength
172 * The length in bytes of the master key in bytes. The length must
173 * match the selected encryption algorithm. Because SRTP uses AES
174 * based encryption only, then master key length may be 16 or 32
175 * bytes (128 or 256 bit master key)
176 *
177 * @param masterSalt
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500178 * SRTP uses the master salt to generate the initialization vector
Alexandre Lision51140e12013-12-02 10:54:09 -0500179 * that in turn is input to compute the session key, session
180 * authentication key and the session salt.
181 *
182 * @param masterSaltLength
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500183 * The length in bytes of the master salt data in bytes. According to
184 * RFC3711 the standard value for the master salt length should
185 * be 14 bytes (112 bit).
Alexandre Lision51140e12013-12-02 10:54:09 -0500186 *
187 * @param ekeyl
188 * The length in bytes of the session encryption key that SRTP shall
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500189 * generate and use. Usually the same length as for the master key
190 * length, however you may use a different length as well.
Alexandre Lision51140e12013-12-02 10:54:09 -0500191 *
192 * @param akeyl
193 * The length in bytes of the session authentication key. SRTP
194 * computes this key and uses it as input to the authentication
195 * algorithm.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500196 * This is usually 160 bits (20 bytes) for @c SrtpAuthenticationSha1Hmac
197 * and 256 bits (32 bytes) for @c SrtpAuthenticationSkeinHmac.
Alexandre Lision51140e12013-12-02 10:54:09 -0500198 *
199 * @param skeyl
200 * The length in bytes of the session salt. SRTP computes this salt
201 * key and uses it as input during encryption. The length usually
202 * is the same as the master salt length.
203 *
204 * @param tagLength
205 * The length is bytes of the authentication tag that SRTP appends
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500206 * to the RTP packet. The @c CryptoContext supports @c SrtpAuthenticationSha1Hmac
207 * with 4 and 10 byte (32 and 80 bits) and @c SrtpAuthenticationSkeinHmac
208 * with 4 and 8 bytes (32 and 64 bits) tag length. Refer to chapter 4.2. in RFC 3711.
Alexandre Lision51140e12013-12-02 10:54:09 -0500209 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500210 CryptoContext(uint32_t ssrc, int32_t roc,
Alexandre Lision51140e12013-12-02 10:54:09 -0500211 int64_t keyDerivRate,
212 const int32_t ealg,
213 const int32_t aalg,
214 uint8_t* masterKey,
215 int32_t masterKeyLength,
216 uint8_t* masterSalt,
217 int32_t masterSaltLength,
218 int32_t ekeyl,
219 int32_t akeyl,
220 int32_t skeyl,
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500221 int32_t tagLength);
222
Alexandre Lision51140e12013-12-02 10:54:09 -0500223 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500224 * @brief Destructor.
Alexandre Lision51140e12013-12-02 10:54:09 -0500225 *
226 * Cleans the SRTP cryptographic context.
227 */
228 ~CryptoContext();
229
230 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500231 * @brief Set the Roll-Over-Counter.
Alexandre Lision51140e12013-12-02 10:54:09 -0500232 *
233 * Ths method sets the upper 32 bit of the 48 bit SRTP packet index
234 * (the roll-over-part)
235 *
236 * @param r
237 * The roll-over-counter
238 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500239 inline void setRoc(uint32_t r) { roc = r; }
Alexandre Lision51140e12013-12-02 10:54:09 -0500240
241 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500242 * @brief Get the Roll-Over-Counter.
Alexandre Lision51140e12013-12-02 10:54:09 -0500243 *
244 * Ths method get the upper 32 bit of the 48 bit SRTP packet index
245 * (the roll-over-part)
246 *
247 * @return The roll-over-counter
248 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500249 inline uint32_t getRoc() const { return roc; }
Alexandre Lision51140e12013-12-02 10:54:09 -0500250
251 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500252 * @brief Perform SRTP encryption.
Alexandre Lision51140e12013-12-02 10:54:09 -0500253 *
254 * This method encrypts <em>and</em> decrypts SRTP payload data. Plain
255 * data gets encrypted, encrypted data get decrypted.
256 *
257 * @param pkt
258 * Pointer to RTP packet buffer, used for F8.
259 *
260 * @param payload
261 * The data to encrypt.
262 *
263 * @param paylen
264 * Length of payload.
265 *
266 * @param index
267 * The 48 bit SRTP packet index. See the <code>guessIndex</code>
268 * method.
269 *
270 * @param ssrc
271 * The RTP SSRC data in <em>host</em> order.
272 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500273 void srtpEncrypt(uint8_t* pkt, uint8_t* payload, uint32_t paylen, uint64_t index, uint32_t ssrc);
Alexandre Lision51140e12013-12-02 10:54:09 -0500274
275 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500276 * @brief Compute the authentication tag.
Alexandre Lision51140e12013-12-02 10:54:09 -0500277 *
278 * Compute the authentication tag according the the paramters in the
279 * SRTP Cryptograhic context.
280 *
281 * @param pkt
282 * Pointer to RTP packet buffer that contains the data to authenticate.
283 *
284 * @param pktlen
285 * Length of the RTP packet buffer
286 *
287 * @param roc
288 * The 32 bit SRTP roll-over-counter.
289 *
290 * @param tag
291 * Points to a buffer that hold the computed tag. This buffer must
292 * be able to hold <code>tagLength</code> bytes.
293 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500294 void srtpAuthenticate(uint8_t* pkt, uint32_t pktlen, uint32_t roc, uint8_t* tag);
Alexandre Lision51140e12013-12-02 10:54:09 -0500295
296 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500297 * @brief Perform key derivation according to SRTP specification
Alexandre Lision51140e12013-12-02 10:54:09 -0500298 *
299 * This method computes the session key, session authentication key and the
300 * session salt key. This method must be called at least once after the
301 * SRTP Cryptograhic context was set up.
302 *
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500303 * This method clears the key data once it was processed by the encryptions'
304 * set key functions.
305 *
Alexandre Lision51140e12013-12-02 10:54:09 -0500306 * @param index
307 * The 48 bit SRTP packet index. See the <code>guessIndex</code>
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500308 * method. Usually 0.
Alexandre Lision51140e12013-12-02 10:54:09 -0500309 */
310 void deriveSrtpKeys(uint64_t index);
311
312 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500313 * @brief Compute (guess) the new SRTP index based on the sequence number of
Alexandre Lision51140e12013-12-02 10:54:09 -0500314 * a received RTP packet.
315 *
316 * The method uses the algorithm show in RFC3711, Appendix A, to compute
317 * the new index.
318 *
319 * @param newSeqNumber
320 * The sequence number of the received RTP packet in host order.
321 *
322 * @return The new SRTP packet index
323 */
324 uint64_t guessIndex(uint16_t newSeqNumber);
325
326 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500327 * @brief Check for packet replay.
Alexandre Lision51140e12013-12-02 10:54:09 -0500328 *
329 * The method check if a received packet is either to old or was already
330 * received.
331 *
332 * The method supports a 64 packet history relative the the given
333 * sequence number.
334 *
335 * @param newSeqNumber
336 * The sequence number of the received RTP packet in host order.
337 *
338 * @return <code>true</code> if no replay, <code>false</code> if packet
339 * is too old ar was already received.
340 */
341 bool checkReplay(uint16_t newSeqNumber);
342
343 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500344 * @brief Update the SRTP packet index.
Alexandre Lision51140e12013-12-02 10:54:09 -0500345 *
346 * Call this method after all checks were successful. See chapter
347 * 3.3.1 in the RFC when to update the ROC and ROC processing.
348 *
349 * @param newSeqNumber
350 * The sequence number of the received RTP packet in host order.
351 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500352 void update(uint16_t newSeqNumber);
Alexandre Lision51140e12013-12-02 10:54:09 -0500353
354 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500355 * @brief Get the length of the SRTP authentication tag in bytes.
Alexandre Lision51140e12013-12-02 10:54:09 -0500356 *
357 * @return the length of the authentication tag.
358 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500359 int32_t getTagLength() const { return tagLength; }
Alexandre Lision51140e12013-12-02 10:54:09 -0500360
361 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500362 * @brief Get the length of the MKI in bytes.
Alexandre Lision51140e12013-12-02 10:54:09 -0500363 *
364 * @return the length of the MKI.
365 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500366 int32_t getMkiLength() const { return mkiLength; }
Alexandre Lision51140e12013-12-02 10:54:09 -0500367
368 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500369 * @brief Get the SSRC of this SRTP Cryptograhic context.
Alexandre Lision51140e12013-12-02 10:54:09 -0500370 *
371 * @return the SSRC.
372 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500373 uint32_t getSsrc() const { return ssrcCtx; }
Alexandre Lision51140e12013-12-02 10:54:09 -0500374
375 /**
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500376 * @brief Set the start (base) number to compute the PRF labels.
377 *
378 * Refer to RFC3711, chapters 4.3.1 and 4.3.2 about values for labels.
379 * CryptoContext computes the labes as follows:
380 *
381 * - labelBase + 0 -> encryption label
382 * - labelBase + 1 -> authentication label
383 * - labelBase + 2 -> salting key label
384 *
385 * The CryptoContext constructor initializes CryptoContext::labelBase
386 * with 0 to comply with RFC 3711 label values.
387 *
388 * Applications may set the #labelBase to other values to use the CryptoContext
389 * for other purposes.
390 */
391 void setLabelbase(uint8_t base) { labelBase = base; }
392
393 /**
394 * @brief Derive a new Crypto Context for use with a new SSRC
Alexandre Lision51140e12013-12-02 10:54:09 -0500395 *
396 * This method returns a new Crypto Context initialized with the data
397 * of this crypto context. Replacing the SSRC, Roll-over-Counter, and
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500398 * the key derivation rate the application can use this Crypto Context
Alexandre Lision51140e12013-12-02 10:54:09 -0500399 * to encrypt / decrypt a new stream (Synchronization source) inside
400 * one RTP session.
401 *
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500402 * Before the application can use this crypto context it must call deriveSrtpKeys().
Alexandre Lision51140e12013-12-02 10:54:09 -0500403 *
404 * @param ssrc
405 * The SSRC for this context
406 * @param roc
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500407 * The Roll-Over-Counter for this context, usually 0
Alexandre Lision51140e12013-12-02 10:54:09 -0500408 * @param keyDerivRate
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500409 * The key derivation rate for this context, usally 0
Alexandre Lision51140e12013-12-02 10:54:09 -0500410 * @return
411 * a new CryptoContext with all relevant data set.
412 */
Alexandre Lision51140e12013-12-02 10:54:09 -0500413 CryptoContext* newCryptoContextForSSRC(uint32_t ssrc, int roc, int64_t keyDerivRate);
414
415private:
416
417 uint32_t ssrcCtx;
418 bool using_mki;
419 uint32_t mkiLength;
420 uint8_t* mki;
421
422 uint32_t roc;
423 uint32_t guessed_roc;
424 uint16_t s_l;
425 int64_t key_deriv_rate;
426
427 /* bitmask for replay check */
428 uint64_t replay_window;
429
430 uint8_t* master_key;
431 uint32_t master_key_length;
432 uint32_t master_key_srtp_use_nb;
433 uint32_t master_key_srtcp_use_nb;
434 uint8_t* master_salt;
435 uint32_t master_salt_length;
436
437 /* Session Encryption, Authentication keys, Salt */
438 int32_t n_e;
439 uint8_t* k_e;
440 int32_t n_a;
441 uint8_t* k_a;
442 int32_t n_s;
443 uint8_t* k_s;
444
445 int32_t ealg;
446 int32_t aalg;
447 int32_t ekeyl;
448 int32_t akeyl;
449 int32_t skeyl;
450 int32_t tagLength;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500451 uint8_t labelBase;
Alexandre Lision51140e12013-12-02 10:54:09 -0500452 bool seqNumSet;
453
454 void* macCtx;
455
456 SrtpSymCrypto* cipher;
457 SrtpSymCrypto* f8Cipher;
458};
459
460#endif
461
462/**
463 * @}
464 */
465#endif
466