|
1 /* |
|
2 * Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: General packet handling routines. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 // INCLUDES |
|
22 #include "srtppacketrtp.h" |
|
23 #include "srtputils.h" |
|
24 #include "srtpcryptohandler.h" |
|
25 #include "srtpcryptocontext.h" |
|
26 #include "srtpmasterkey.h" |
|
27 #include "srtpmastersalt.h" |
|
28 |
|
29 // ----------------------------------------------------------------------------- |
|
30 // CSRTPPacketRTP::CSRTPPacketRTP |
|
31 // ----------------------------------------------------------------------------- |
|
32 // |
|
33 CSRTPPacketRTP::CSRTPPacketRTP(const TDesC8& aPacket, |
|
34 CSRTPCryptoHandler& aHandler) |
|
35 : CSRTPPacket(aPacket, aHandler), |
|
36 iSequenceNumber(0), |
|
37 iPacketIndex(0) |
|
38 { |
|
39 |
|
40 } |
|
41 |
|
42 // ----------------------------------------------------------------------------- |
|
43 // CSRTPPacketRTP::~CSRTPPacketRTP |
|
44 // ----------------------------------------------------------------------------- |
|
45 // |
|
46 CSRTPPacketRTP::~CSRTPPacketRTP() |
|
47 { |
|
48 |
|
49 } |
|
50 |
|
51 // --------------------------------------------------------------------------- |
|
52 // Two-phased constructor. |
|
53 // |
|
54 // --------------------------------------------------------------------------- |
|
55 // |
|
56 CSRTPPacketRTP* CSRTPPacketRTP::NewL(const TDesC8& aPacket, |
|
57 CSRTPCryptoHandler& aHandler) |
|
58 { |
|
59 CSRTPPacketRTP* self = new( ELeave )CSRTPPacketRTP( aPacket, aHandler); |
|
60 CleanupStack::PushL( self ); |
|
61 self->ConstructL(); |
|
62 CleanupStack::Pop( self ); |
|
63 return self; |
|
64 } |
|
65 |
|
66 // ----------------------------------------------------------------------------- |
|
67 // void CSRTPPacketRTP::ConstructL |
|
68 // ----------------------------------------------------------------------------- |
|
69 // |
|
70 void CSRTPPacketRTP::ConstructL() |
|
71 { |
|
72 CSRTPPacket::ConstructL(); |
|
73 UpdateHeaderLengthL(); |
|
74 |
|
75 SRTP_DEBUG_TINT_VALUE( "RTP header length", iHeaderLength ); |
|
76 |
|
77 UpdateSequenceNumber(); |
|
78 UpdatePayloadLength(); |
|
79 |
|
80 SRTP_DEBUG_TINT_VALUE( "RTP payload length", iPayloadLength ); |
|
81 |
|
82 UpdatePayload(); |
|
83 |
|
84 } |
|
85 // --------------------------------------------------------------------------- |
|
86 // CSRTPPacketRTP::UpdateHeaderLengthL() |
|
87 // --------------------------------------------------------------------------- |
|
88 // |
|
89 void CSRTPPacketRTP::UpdateHeaderLengthL() |
|
90 { |
|
91 //TUint payloadOffset = KMinSizeRtpHeader; |
|
92 TInt size = iPacket.Length(); |
|
93 if (size < KMinSizeRtpHeader) |
|
94 { |
|
95 User::Leave(KErrCorrupt); |
|
96 } |
|
97 const TUint8 *pointer = iDataP; |
|
98 |
|
99 //CC |
|
100 TUint8 numCSRC = static_cast<TUint8>( iDataP[0] & 0x0F ); |
|
101 |
|
102 //header extension |
|
103 TUint8 headerExt = static_cast<TUint8>( ( iDataP[0] & 0x10 ) >> 4 ); |
|
104 |
|
105 //go to the end of SSRC |
|
106 pointer +=KMinSizeRtpHeader; |
|
107 |
|
108 if (numCSRC) |
|
109 { |
|
110 pointer += numCSRC * 4; |
|
111 } |
|
112 |
|
113 if (headerExt) |
|
114 { |
|
115 // Make sure there is a header extension to read |
|
116 if ( ( size - ( pointer - iDataP ) ) < 4 ) |
|
117 { |
|
118 User::Leave(KErrCorrupt); |
|
119 } |
|
120 |
|
121 // bypass header extension type |
|
122 pointer += 2; |
|
123 |
|
124 // header extension length in number of 32-bit words |
|
125 TUint16 extLength = TSRTPUtils::Read16( pointer ); |
|
126 pointer += 2; |
|
127 |
|
128 // jump the extension length |
|
129 pointer += extLength * 4; |
|
130 |
|
131 // Make sure the extension length is valid |
|
132 if ( (size - ( pointer - iDataP ) ) < (extLength * 4) ) |
|
133 { |
|
134 User::Leave(KErrCorrupt); |
|
135 } |
|
136 } |
|
137 |
|
138 iHeaderLength = pointer - iDataP; |
|
139 if ( iHeaderLength > size ) |
|
140 { |
|
141 User::Leave( KErrCorrupt ); |
|
142 } |
|
143 } |
|
144 |
|
145 // --------------------------------------------------------------------------- |
|
146 // CSRTPPacketRTP::UpdatePayloadLength() |
|
147 // --------------------------------------------------------------------------- |
|
148 // |
|
149 void CSRTPPacketRTP::UpdatePayloadLength() |
|
150 { |
|
151 // In RTP case the payload length is easy to calculate |
|
152 //This is only for sending the packe while payload is 512bits |
|
153 TInt packetlen= iPacket.Length() - iHeaderLength; |
|
154 iPayloadLength = packetlen; |
|
155 if ( iPacket.Length() <= iHeaderLength ) |
|
156 { |
|
157 iPayloadLength = 0; |
|
158 } |
|
159 } |
|
160 |
|
161 // --------------------------------------------------------------------------- |
|
162 // CSRTPPacketRTP::UpdateSeqNumber() |
|
163 // --------------------------------------------------------------------------- |
|
164 // |
|
165 void CSRTPPacketRTP::UpdateSequenceNumber( ) |
|
166 { |
|
167 // search the Seq number and update iCurrentSeq here |
|
168 const TUint8 *pointer = iDataP; |
|
169 pointer+=2; |
|
170 |
|
171 iSequenceNumber = static_cast<TUint16>( TSRTPUtils::Read16( pointer ) ); |
|
172 } |
|
173 |
|
174 |
|
175 // --------------------------------------------------------------------------- |
|
176 // CSRTPPacketRTP::CountEncryptedPacketSizeL() |
|
177 // --------------------------------------------------------------------------- |
|
178 // |
|
179 TUint CSRTPPacketRTP::CountEncryptedPacketSizeL() |
|
180 { |
|
181 TUint srtpPacketSize = iHeaderLength + iPayloadLength; |
|
182 srtpPacketSize += iHandler.Context().MasterKey().MKI().Length(); |
|
183 //in Normal case |
|
184 if ( iHandler.Context().CryptoParams().iSrtpAuthAlg != EAuthNull ) |
|
185 { |
|
186 srtpPacketSize += iHandler.Context().CryptoParams().iSrtpAuthTagLen/8; |
|
187 } |
|
188 if (!TagWithROCLengthL() &&( |
|
189 iHandler.Context().CryptoParams().iSrtpAuthAlg != EAuthNull && |
|
190 iHandler.Context().CryptoParams().iSrtpAuthAlg != EAuthHMAC_SHA1)) |
|
191 { |
|
192 srtpPacketSize -= KSRTPROCLength4; |
|
193 } |
|
194 if (!TagWithROCLengthL() && |
|
195 iHandler.Context().CryptoParams().iSrtpAuthAlg == EAuthRCCm1) |
|
196 { |
|
197 srtpPacketSize -= (KSRTPAuthTagLength80/8); |
|
198 } |
|
199 return srtpPacketSize; |
|
200 } |
|
201 |
|
202 |
|
203 // --------------------------------------------------------------------------- |
|
204 // CSRTPPacketRTP::CreateEncryptedPacketL() |
|
205 // --------------------------------------------------------------------------- |
|
206 // |
|
207 HBufC8* CSRTPPacketRTP::CreateEncryptedPacketL(TUint8* aEncryptedPayloadPtr) |
|
208 { |
|
209 // create encrypted SRTP packet |
|
210 // first count needed packet size |
|
211 TUint srtpPacketSize = CountEncryptedPacketSizeL(); |
|
212 |
|
213 return CopyHeaderAndPayloadL(srtpPacketSize, aEncryptedPayloadPtr); |
|
214 } |
|
215 |
|
216 |
|
217 // --------------------------------------------------------------------------- |
|
218 // CSRTPPacketRTP::CountSenderPacketIndex() |
|
219 // --------------------------------------------------------------------------- |
|
220 // |
|
221 void CSRTPPacketRTP::CountSenderPacketIndex() |
|
222 { |
|
223 TUint32 roc= iHandler.ROC();//note it uses local ROC |
|
224 |
|
225 iPacketIndex = ((65536/*K2EXP16*/* roc) + iSequenceNumber); |
|
226 |
|
227 } |
|
228 |
|
229 |
|
230 // --------------------------------------------------------------------------- |
|
231 // CSRTPPacketRTP::SequenceNumber() |
|
232 // --------------------------------------------------------------------------- |
|
233 // |
|
234 TUint16 CSRTPPacketRTP::SequenceNumber() |
|
235 { |
|
236 return iSequenceNumber; |
|
237 } |
|
238 |
|
239 // --------------------------------------------------------------------------- |
|
240 // CSRTPPacketRTP::PacketIndex() |
|
241 // --------------------------------------------------------------------------- |
|
242 // |
|
243 TUint64 CSRTPPacketRTP::PacketIndex() |
|
244 { |
|
245 return iPacketIndex; |
|
246 } |
|
247 |
|
248 // --------------------------------------------------------------------------- |
|
249 // CSRTPPacketRTP::SetPacketIndex() |
|
250 // --------------------------------------------------------------------------- |
|
251 // |
|
252 void CSRTPPacketRTP::SetPacketIndex(TUint64 aPacketIndex) |
|
253 { |
|
254 iPacketIndex = aPacketIndex; |
|
255 } |
|
256 |
|
257 // --------------------------------------------------------------------------- |
|
258 // CSRTPPacketRTP::GetSenderROC |
|
259 // --------------------------------------------------------------------------- |
|
260 // |
|
261 TUint32 CSRTPPacketRTP::GetSenderROC() |
|
262 { |
|
263 //Note that SenderROC is now only attached with RTP/SRTP packet |
|
264 /*RCCm1 and RCCm2 |
|
265 Only when SEQ % R (ROC transmission rate) =0 |
|
266 Then there is attached sender ROC in the packet 4 octets before MAC |
|
267 so after payload there is 14 (4+ 10) octets if HMAC-SHA1-80 is used |
|
268 */ |
|
269 /*RCCm3 |
|
270 Only when SEQ % R (ROC transmission rate )=0 |
|
271 Then there is attached sender ROC in the packet 4 octets after packet payload |
|
272 but no MAC |
|
273 */ |
|
274 const TUint8 *pointer = iDataP; |
|
275 pointer+= iHeaderLength; |
|
276 pointer+= iPayloadLength; |
|
277 pointer+= iHandler.Context().MasterKey().MKI().Length(); |
|
278 iSenderROC = static_cast<TUint16>( TSRTPUtils::Read32( pointer ) ); |
|
279 |
|
280 //return |
|
281 return iSenderROC; |
|
282 } |
|
283 |
|
284 // --------------------------------------------------------------------------- |
|
285 // CSRTPPacketRTP::TagWithROCLengthL() |
|
286 // --------------------------------------------------------------------------- |
|
287 // |
|
288 TBool CSRTPPacketRTP::TagWithROCLengthL() |
|
289 { |
|
290 //mode 1 and 2 add ROC when SEQ%TransRate =0 |
|
291 //mode 1 will not have any tag if SEQ%TransRate !=0 |
|
292 TReal remainder; |
|
293 TUint16 rate = iHandler.Context().CryptoParams().iROCTransRate; |
|
294 User::LeaveIfError( Math::Mod(remainder ,iSequenceNumber,rate)); |
|
295 if (remainder==0 && |
|
296 ((iHandler.Context().CryptoParams().iSrtpAuthAlg == EAuthRCCm1 )|| |
|
297 (iHandler.Context().CryptoParams().iSrtpAuthAlg == EAuthRCCm2) || |
|
298 (iHandler.Context().CryptoParams().iSrtpAuthAlg == EAuthRCCm3))) |
|
299 { |
|
300 return ETrue; |
|
301 } |
|
302 return EFalse; |
|
303 } |
|
304 |
|
305 |
|
306 |
|
307 // VIRTUAL functions |
|
308 HBufC8* CSRTPPacketRTP::CreateDecryptedPacketL(TUint8* /*aDecryptedPayloadPtr*/) |
|
309 { |
|
310 ////should call inherited class |
|
311 User::Leave(KErrTotalLossOfPrecision); |
|
312 return NULL; |
|
313 } |
|
314 |
|
315 TPtrC8 CSRTPPacketRTP::AuthenticationTag() |
|
316 { |
|
317 //should call inherited class |
|
318 return NULL; |
|
319 } |
|
320 |
|
321 TPtrC8 CSRTPPacketRTP::MasterKeyIdentifier() |
|
322 { |
|
323 ////should call inherited class |
|
324 return NULL; |
|
325 } |
|
326 |