blob: 50c29a9ad38b024353108cd61b2b88683906c591 [file] [log] [blame]
Alexandre Lision51140e12013-12-02 10:54:09 -05001/*
Alexandre Lisione24852d2014-02-04 13:13:02 -05002 Copyright (C) 2006-2009 Werner Dittmann
Alexandre Lision51140e12013-12-02 10:54:09 -05003
4 This program is free software: you can redistribute it and/or modify
Alexandre Lisione24852d2014-02-04 13:13:02 -05005 it under the terms of the GNU General Public License as published by
Alexandre Lision51140e12013-12-02 10:54:09 -05006 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program 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
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
Alexandre Lisione24852d2014-02-04 13:13:02 -050018/*F
Alexandre Lision51140e12013-12-02 10:54:09 -050019 * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
20 */
21#include <sstream>
22
Alexandre Lisione24852d2014-02-04 13:13:02 -050023#include <libzrtpcpp/crypto/ZrtpDH.h>
24#include <libzrtpcpp/crypto/hmac256.h>
25#include <libzrtpcpp/crypto/sha256.h>
26#include <libzrtpcpp/crypto/hmac384.h>
27#include <libzrtpcpp/crypto/sha384.h>
28#include <libzrtpcpp/crypto/aesCFB.h>
29#include <libzrtpcpp/crypto/twoCFB.h>
Alexandre Lision51140e12013-12-02 10:54:09 -050030
31#include <libzrtpcpp/ZRtp.h>
32#include <libzrtpcpp/ZrtpStateClass.h>
Alexandre Lisione24852d2014-02-04 13:13:02 -050033#include <libzrtpcpp/ZIDFile.h>
34#include <libzrtpcpp/ZIDRecord.h>
Alexandre Lision51140e12013-12-02 10:54:09 -050035#include <libzrtpcpp/Base32.h>
36
37using namespace GnuZrtpCodes;
38
39/* disabled...but used in testing and debugging, probably should have a
40 controlling #define...
41 *
42static void hexdump(const char* title, const unsigned char *s, int l) {
43 int n=0;
44
45 if (s == NULL) return;
46
47 fprintf(stderr, "%s",title);
48 for( ; n < l ; ++n)
49 {
50 if((n%16) == 0)
51 fprintf(stderr, "\n%04x",n);
52 fprintf(stderr, " %02x",s[n]);
53 }
54 fprintf(stderr, "\n");
55}
Alexandre Lisione24852d2014-02-04 13:13:02 -050056 */
Alexandre Lision51140e12013-12-02 10:54:09 -050057
58/*
59 * This method simplifies detection of libzrtpcpp inside Automake, configure
60 * and friends
61 */
62#ifdef __cplusplus
63extern "C" {
64#endif
65 int ZrtpAvailable()
66 {
67 return 1;
68 }
69#ifdef __cplusplus
70}
71#endif
72
73ZRtp::ZRtp(uint8_t *myZid, ZrtpCallback *cb, std::string id, ZrtpConfigure* config, bool mitmm, bool sasSignSupport):
74 callback(cb), dhContext(NULL), DHss(NULL), auxSecret(NULL), auxSecretLength(0), rs1Valid(false),
Alexandre Lisione24852d2014-02-04 13:13:02 -050075 rs2Valid(false), msgShaContext(NULL), multiStream(false), multiStreamAvailable(false), pbxSecretTmp(NULL),
76 configureAlgos(*config) {
Alexandre Lision51140e12013-12-02 10:54:09 -050077
78 enableMitmEnrollment = config->isTrustedMitM();
79 paranoidMode = config->isParanoidMode();
80
81 // setup the implicit hash function pointers and length
82 hashLengthImpl = SHA256_DIGEST_LENGTH;
83 hashFunctionImpl = sha256;
84 hashListFunctionImpl = sha256;
85
86 hmacFunctionImpl = hmac_sha256;
87 hmacListFunctionImpl = hmac_sha256;
88
89 /*
90 * Generate H0 as a random number (256 bits, 32 bytes) and then
91 * the hash chain, refer to chapter 9. Use the implicit hash function.
92 */
93 randomZRTP(H0, HASH_IMAGE_SIZE);
94 sha256(H0, HASH_IMAGE_SIZE, H1); // hash H0 and generate H1
95 sha256(H1, HASH_IMAGE_SIZE, H2); // H2
96 sha256(H2, HASH_IMAGE_SIZE, H3); // H3
97
Alexandre Lisione24852d2014-02-04 13:13:02 -050098 zrtpHello.configureHello(&configureAlgos);
99 zrtpHello.setH3(H3); // set H3 in Hello, included in helloHash
Alexandre Lision907ed2e2014-02-04 10:33:09 -0500100
Alexandre Lisione24852d2014-02-04 13:13:02 -0500101 memcpy(zid, myZid, ZID_SIZE);
102 zrtpHello.setZid(zid);
Alexandre Lision907ed2e2014-02-04 10:33:09 -0500103
Alexandre Lisione24852d2014-02-04 13:13:02 -0500104 if (mitmm) // this session acts for a trusted MitM (PBX)
105 zrtpHello.setMitmMode();
Alexandre Lision907ed2e2014-02-04 10:33:09 -0500106
Alexandre Lisione24852d2014-02-04 13:13:02 -0500107 if (sasSignSupport) // the application supports SAS signing
108 zrtpHello.setSasSign();
Alexandre Lision907ed2e2014-02-04 10:33:09 -0500109
Alexandre Lisione24852d2014-02-04 13:13:02 -0500110 setClientId(id); // set id, compute HMAC and final helloHash
Alexandre Lision51140e12013-12-02 10:54:09 -0500111
112 stateEngine = new ZrtpStateClass(this);
113}
114
115ZRtp::~ZRtp() {
116 stopZrtp();
117 if (DHss != NULL) {
118 delete DHss;
119 DHss = NULL;
120 }
121 if (stateEngine != NULL) {
122 delete stateEngine;
123 stateEngine = NULL;
124 }
125 if (dhContext != NULL) {
126 delete dhContext;
127 dhContext = NULL;
128 }
129 if (msgShaContext != NULL) {
130 closeHashCtx(msgShaContext, NULL);
131 msgShaContext = NULL;
132 }
133 if (auxSecret != NULL) {
134 delete auxSecret;
135 auxSecret = NULL;
136 auxSecretLength = 0;
137 }
138 memset(hmacKeyI, 0, MAX_DIGEST_LENGTH);
139 memset(hmacKeyR, 0, MAX_DIGEST_LENGTH);
140
141 memset(zrtpKeyI, 0, MAX_DIGEST_LENGTH);
142 memset(zrtpKeyR, 0, MAX_DIGEST_LENGTH);
143 /*
144 * Clear the Initiator's srtp key and salt
145 */
146 memset(srtpKeyI, 0, MAX_DIGEST_LENGTH);
147 memset(srtpSaltI, 0, MAX_DIGEST_LENGTH);
148 /*
149 * Clear he Responder's srtp key and salt
150 */
151 memset(srtpKeyR, 0, MAX_DIGEST_LENGTH);
152 memset(srtpSaltR, 0, MAX_DIGEST_LENGTH);
153
154 memset(zrtpSession, 0, MAX_DIGEST_LENGTH);
155}
156
Alexandre Lisione24852d2014-02-04 13:13:02 -0500157void ZRtp::processZrtpMessage(uint8_t *message, uint32_t pSSRC) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500158 Event_t ev;
159
160 peerSSRC = pSSRC;
161 ev.type = ZrtpPacket;
162 ev.packet = message;
163
164 if (stateEngine != NULL) {
165 stateEngine->processEvent(&ev);
166 }
167}
168
169void ZRtp::processTimeout() {
170 Event_t ev;
171
172 ev.type = Timer;
173 if (stateEngine != NULL) {
174 stateEngine->processEvent(&ev);
175 }
176}
177
178#ifdef oldgoclear
179bool ZRtp::handleGoClear(uint8_t *message)
180{
181 char *msg, first, last;
182
183 msg = (char *)message + 4;
184 first = tolower(*msg);
185 last = tolower(*(msg+6));
186
187 if (first == 'g' && last == 'r') {
188 Event_t ev;
189
190 ev.type = ZrtpGoClear;
191 ev.packet = message;
192 if (stateEngine != NULL) {
193 stateEngine->processEvent(&ev);
194 }
195 return true;
196 }
197 else {
198 return false;
199 }
200}
201#endif
202
203void ZRtp::startZrtpEngine() {
204 Event_t ev;
205
206 if (stateEngine != NULL && stateEngine->inState(Initial)) {
207 ev.type = ZrtpInitial;
208 stateEngine->processEvent(&ev);
209 }
210}
211
212void ZRtp::stopZrtp() {
213 Event_t ev;
214
215 if (stateEngine != NULL) {
216 ev.type = ZrtpClose;
217 stateEngine->processEvent(&ev);
218 }
219}
220
221bool ZRtp::inState(int32_t state)
222{
223 if (stateEngine != NULL) {
224 return stateEngine->inState(state);
225 }
226 else {
227 return false;
228 }
229}
230
231ZrtpPacketHello* ZRtp::prepareHello() {
Alexandre Lisione24852d2014-02-04 13:13:02 -0500232 return &zrtpHello;
Alexandre Lision51140e12013-12-02 10:54:09 -0500233}
234
235ZrtpPacketHelloAck* ZRtp::prepareHelloAck() {
236 return &zrtpHelloAck;
237}
238
239/*
240 * At this point we will assume the role of Initiator. This role may change
241 * in case we have a commit-clash. Refer to chapter 5.2 in the spec how
242 * to break this tie.
243 */
244ZrtpPacketCommit* ZRtp::prepareCommit(ZrtpPacketHello *hello, uint32_t* errMsg) {
245
Alexandre Lisione24852d2014-02-04 13:13:02 -0500246 sendInfo(Info, InfoHelloReceived);
Alexandre Lision907ed2e2014-02-04 10:33:09 -0500247
Alexandre Lisione24852d2014-02-04 13:13:02 -0500248 if (memcmp(hello->getVersion(), zrtpVersion, ZRTP_WORD_SIZE-1) != 0) {
249 *errMsg = UnsuppZRTPVersion;
Alexandre Lision907ed2e2014-02-04 10:33:09 -0500250 return NULL;
251 }
Alexandre Lision51140e12013-12-02 10:54:09 -0500252 // Save our peer's (presumably the Responder) ZRTP id
253 memcpy(peerZid, hello->getZid(), ZID_SIZE);
Alexandre Lisione24852d2014-02-04 13:13:02 -0500254 if (memcmp(peerZid, zid, ZID_SIZE) == 0) { // peers have same ZID????
Alexandre Lision51140e12013-12-02 10:54:09 -0500255 *errMsg = EqualZIDHello;
256 return NULL;
257 }
258 memcpy(peerH3, hello->getH3(), HASH_IMAGE_SIZE);
259
260 /*
261 * The Following section extracts the algorithm from the peer's Hello
262 * packet. Always the preferend offered algorithms are
263 * used. If the received Hello does not contain algo specifiers
264 * or offers only unsupported optional algos then replace
265 * these with mandatory algos and put them into the Commit packet.
266 * Refer to the findBest*() functions.
267 * If this is a MultiStream ZRTP object then do not get the cipher,
268 * authentication from hello packet but use the pre-initialized values
269 * as proposed by the standard. If we switch to responder mode the
270 * commit packet may contain other algos - see function
271 * prepareConfirm2MultiStream(...).
272 */
273 sasType = findBestSASType(hello);
274
275 if (!multiStream) {
Alexandre Lisione24852d2014-02-04 13:13:02 -0500276 authLength = findBestAuthLen(hello);
277 pubKey = findBestPubkey(hello);
278 cipher = findBestCipher(hello, pubKey);
279 hash = findBestHash(hello);
Alexandre Lision51140e12013-12-02 10:54:09 -0500280 multiStreamAvailable = checkMultiStream(hello);
281 }
282 else {
283 if (checkMultiStream(hello)) {
284 return prepareCommitMultiStream(hello);
285 }
286 else {
287 // we are in multi-stream but peer does not offer multi-stream
288 // return error code to other party - unsupported PK, must be Mult
289 *errMsg = UnsuppPKExchange;
290 return NULL;
291 }
292 }
293 setNegotiatedHash(hash);
294
295 // Modify here when introducing new DH key agreement, for example
296 // elliptic curves.
297 dhContext = new ZrtpDH(pubKey->getName());
298 dhContext->generatePublicKey();
299
300 dhContext->getPubKeyBytes(pubKeyBytes);
301 sendInfo(Info, InfoCommitDHGenerated);
302
303 // Prepare IV data that we will use during confirm packet encryption.
304 randomZRTP(randomIV, sizeof(randomIV));
305
306 /*
307 * Prepare our DHPart2 packet here. Required to compute HVI. If we stay
308 * in Initiator role then we reuse this packet later in prepareDHPart2().
Alexandre Lisione24852d2014-02-04 13:13:02 -0500309 * To create this DH packet we have to compute the retained secret ids
310 * first. Thus get our peer's retained secret data first.
Alexandre Lision51140e12013-12-02 10:54:09 -0500311 */
Alexandre Lisione24852d2014-02-04 13:13:02 -0500312 ZIDRecord zidRec(peerZid);
313 ZIDFile *zidFile = ZIDFile::getInstance();
314 zidFile->getRecord(&zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -0500315
316 //Compute the Initator's and Responder's retained secret ids.
317 computeSharedSecretSet(zidRec);
318
319 // Check if a PBX application set the MitM flag.
Alexandre Lisione24852d2014-02-04 13:13:02 -0500320 if (hello->isMitmMode()) {
321 mitmSeen = true;
322 }
323 // Flag to record that fact that we have a MitM key of the other peer.
324 peerIsEnrolled = zidRec.isMITMKeyAvailable();
Alexandre Lision51140e12013-12-02 10:54:09 -0500325
326 signSasSeen = hello->isSasSign();
327 // Construct a DHPart2 message (Initiator's DH message). This packet
328 // is required to compute the HVI (Hash Value Initiator), refer to
329 // chapter 5.4.1.1.
330
331 // Fill the values in the DHPart2 packet
332 zrtpDH2.setPubKeyType(pubKey->getName());
333 zrtpDH2.setMessageType((uint8_t*)DHPart2Msg);
334 zrtpDH2.setRs1Id(rs1IDi);
335 zrtpDH2.setRs2Id(rs2IDi);
336 zrtpDH2.setAuxSecretId(auxSecretIDi);
337 zrtpDH2.setPbxSecretId(pbxSecretIDi);
338 zrtpDH2.setPv(pubKeyBytes);
339 zrtpDH2.setH1(H1);
340
341 int32_t len = zrtpDH2.getLength() * ZRTP_WORD_SIZE;
342
343 // Compute HMAC over DH2, excluding the HMAC field (HMAC_SIZE)
344 // and store in DH2. Key to HMAC is H0, use HASH_IMAGE_SIZE bytes only.
345 // Must use implicit HMAC functions.
346 uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];
347 uint32_t macLen;
348 hmacFunctionImpl(H0, HASH_IMAGE_SIZE, (uint8_t*)zrtpDH2.getHeaderBase(), len-(HMAC_SIZE), hmac, &macLen);
349 zrtpDH2.setHMAC(hmac);
350
351 // Compute the HVI, refer to chapter 5.4.1.1 of the specification
352 computeHvi(&zrtpDH2, hello);
353
Alexandre Lisione24852d2014-02-04 13:13:02 -0500354 zrtpCommit.setZid(zid);
Alexandre Lision51140e12013-12-02 10:54:09 -0500355 zrtpCommit.setHashType((uint8_t*)hash->getName());
356 zrtpCommit.setCipherType((uint8_t*)cipher->getName());
357 zrtpCommit.setAuthLen((uint8_t*)authLength->getName());
358 zrtpCommit.setPubKeyType((uint8_t*)pubKey->getName());
359 zrtpCommit.setSasType((uint8_t*)sasType->getName());
360 zrtpCommit.setHvi(hvi);
361 zrtpCommit.setH2(H2);
362
363 len = zrtpCommit.getLength() * ZRTP_WORD_SIZE;
364
365 // Compute HMAC over Commit, excluding the HMAC field (HMAC_SIZE)
366 // and store in Hello. Key to HMAC is H1, use HASH_IMAGE_SIZE bytes only.
367 // Must use implicit HMAC functions.
368 hmacFunctionImpl(H1, HASH_IMAGE_SIZE, (uint8_t*)zrtpCommit.getHeaderBase(), len-(HMAC_SIZE), hmac, &macLen);
369 zrtpCommit.setHMAC(hmac);
370
371 // hash first messages to produce overall message hash
372 // First the Responder's Hello message, second the Commit (always Initator's).
373 // Must use negotiated hash.
Alexandre Lisione24852d2014-02-04 13:13:02 -0500374 int32_t helloLen = hello->getLength() * ZRTP_WORD_SIZE;
Alexandre Lision51140e12013-12-02 10:54:09 -0500375 msgShaContext = createHashCtx();
376 hashCtxFunction(msgShaContext, (unsigned char*)hello->getHeaderBase(), helloLen);
377 hashCtxFunction(msgShaContext, (unsigned char*)zrtpCommit.getHeaderBase(), len);
378
379 // store Hello data temporarily until we can check HMAC after receiving Commit as
380 // Responder or DHPart1 as Initiator
381 storeMsgTemp(hello);
382
Alexandre Lisione24852d2014-02-04 13:13:02 -0500383 // calculate hash over the received Hello packet - is peer's hello hash.
384 // Use implicit hash algorithm
385 hashFunctionImpl((unsigned char*)hello->getHeaderBase(), helloLen, peerHelloHash);
386 memcpy(peerHelloVersion, hello->getVersion(), ZRTP_WORD_SIZE);
387 peerHelloVersion[ZRTP_WORD_SIZE] = 0;
388
Alexandre Lision51140e12013-12-02 10:54:09 -0500389 return &zrtpCommit;
390}
391
392ZrtpPacketCommit* ZRtp::prepareCommitMultiStream(ZrtpPacketHello *hello) {
393
394 randomZRTP(hvi, ZRTP_WORD_SIZE*4); // This is the Multi-Stream NONCE size
395
Alexandre Lisione24852d2014-02-04 13:13:02 -0500396 zrtpCommit.setZid(zid);
Alexandre Lision51140e12013-12-02 10:54:09 -0500397 zrtpCommit.setHashType((uint8_t*)hash->getName());
398 zrtpCommit.setCipherType((uint8_t*)cipher->getName());
399 zrtpCommit.setAuthLen((uint8_t*)authLength->getName());
Alexandre Lisione24852d2014-02-04 13:13:02 -0500400 zrtpCommit.setPubKeyType((uint8_t*)"Mult"); // this is fixed because of Multi Stream mode
Alexandre Lision51140e12013-12-02 10:54:09 -0500401 zrtpCommit.setSasType((uint8_t*)sasType->getName());
402 zrtpCommit.setNonce(hvi);
403 zrtpCommit.setH2(H2);
404
405 int32_t len = zrtpCommit.getLength() * ZRTP_WORD_SIZE;
406
407 // Compute HMAC over Commit, excluding the HMAC field (HMAC_SIZE)
408 // and store in Hello. Key to HMAC is H1, use HASH_IMAGE_SIZE bytes only.
409 // Must use the implicit HMAC function.
410 uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];
411 uint32_t macLen;
412 hmacFunctionImpl(H1, HASH_IMAGE_SIZE, (uint8_t*)zrtpCommit.getHeaderBase(), len-(HMAC_SIZE), hmac, &macLen);
413 zrtpCommit.setHMACMulti(hmac);
414
415
416 // hash first messages to produce overall message hash
417 // First the Responder's Hello message, second the Commit
418 // (always Initator's).
419 // Must use the negotiated hash.
420 msgShaContext = createHashCtx();
421
422 int32_t helloLen = hello->getLength() * ZRTP_WORD_SIZE;
423 hashCtxFunction(msgShaContext, (unsigned char*)hello->getHeaderBase(), helloLen);
424 hashCtxFunction(msgShaContext, (unsigned char*)zrtpCommit.getHeaderBase(), len);
425
426 // store Hello data temporarily until we can check HMAC after receiving Commit as
427 // Responder or DHPart1 as Initiator
428 storeMsgTemp(hello);
429
Alexandre Lisione24852d2014-02-04 13:13:02 -0500430 // calculate hash over the received Hello packet - is peer's hello hash.
431 // Use implicit hash algorithm
432 hashFunctionImpl((unsigned char*)hello->getHeaderBase(), helloLen, peerHelloHash);
433 memcpy(peerHelloVersion, hello->getVersion(), ZRTP_WORD_SIZE);
434 peerHelloVersion[ZRTP_WORD_SIZE] = 0;
435
Alexandre Lision51140e12013-12-02 10:54:09 -0500436 return &zrtpCommit;
437}
438
439/*
Alexandre Lisione24852d2014-02-04 13:13:02 -0500440 * At this point we will take the role of the Responder. We may have been in
Alexandre Lision51140e12013-12-02 10:54:09 -0500441 * the role of the Initiator before and already sent a commit packet that
442 * clashed with a commit packet from our peer. If our HVI was lower than our
443 * peer's HVI then we switched to Responder and handle our peer's commit packet
444 * here. This method takes care to delete and refresh data left over from a
445 * possible Initiator preparation. This belongs to prepared DH data, message
446 * hash SHA context
447 */
448ZrtpPacketDHPart* ZRtp::prepareDHPart1(ZrtpPacketCommit *commit, uint32_t* errMsg) {
449
450 sendInfo(Info, InfoRespCommitReceived);
451
Alexandre Lisione24852d2014-02-04 13:13:02 -0500452 // The following code check the hash chain according chapter 10 to detect
453 // false ZRTP packets.
Alexandre Lision51140e12013-12-02 10:54:09 -0500454 // Must use the implicit hash function.
455 uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];
456 memcpy(peerH2, commit->getH2(), HASH_IMAGE_SIZE);
457 hashFunctionImpl(peerH2, HASH_IMAGE_SIZE, tmpH3);
458
459 if (memcmp(tmpH3, peerH3, HASH_IMAGE_SIZE) != 0) {
460 *errMsg = IgnorePacket;
461 return NULL;
462 }
463
464 // Check HMAC of previous Hello packet stored in temporary buffer. The
465 // HMAC key of peer's Hello packet is peer's H2 that is contained in the
466 // Commit packet. Refer to chapter 9.1.
467 if (!checkMsgHmac(peerH2)) {
468 sendInfo(Severe, SevereHelloHMACFailed);
469 *errMsg = CriticalSWError;
470 return NULL;
471 }
472
473 // check if we support the commited Cipher type
474 AlgorithmEnum* cp = &zrtpSymCiphers.getByName((const char*)commit->getCipherType());
475 if (!cp->isValid()) { // no match - something went wrong
476 *errMsg = UnsuppCiphertype;
477 return NULL;
478 }
479 cipher = cp;
480
481 // check if we support the commited Authentication length
482 cp = &zrtpAuthLengths.getByName((const char*)commit->getAuthLen());
483 if (!cp->isValid()) { // no match - something went wrong
484 *errMsg = UnsuppSRTPAuthTag;
485 return NULL;
486 }
487 authLength = cp;
488
489 // check if we support the commited hash type
490 cp = &zrtpHashes.getByName((const char*)commit->getHashType());
491 if (!cp->isValid()) { // no match - something went wrong
492 *errMsg = UnsuppHashType;
493 return NULL;
494 }
495 // check if the peer's commited hash is the same that we used when
496 // preparing our commit packet. If not do the necessary resets and
497 // recompute some data.
498 if (*(int32_t*)(hash->getName()) != *(int32_t*)(cp->getName())) {
499 hash = cp;
500 setNegotiatedHash(hash);
Alexandre Lisione24852d2014-02-04 13:13:02 -0500501
502 ZIDRecord zidRec(peerZid);
503 ZIDFile *zidFile = ZIDFile::getInstance();
504 zidFile->getRecord(&zidRec);
505
Alexandre Lision51140e12013-12-02 10:54:09 -0500506 // Compute the Initator's and Responder's retained secret ids
507 // with the committed hash.
508 computeSharedSecretSet(zidRec);
509 }
Alexandre Lisione24852d2014-02-04 13:13:02 -0500510
Alexandre Lision51140e12013-12-02 10:54:09 -0500511 // check if we support the commited pub key type
512 cp = &zrtpPubKeys.getByName((const char*)commit->getPubKeysType());
513 if (!cp->isValid()) { // no match - something went wrong
514 *errMsg = UnsuppPKExchange;
515 return NULL;
516 }
517 pubKey = cp;
518
519 // check if we support the commited SAS type
520 cp = &zrtpSasTypes.getByName((const char*)commit->getSasType());
521 if (!cp->isValid()) { // no match - something went wrong
522 *errMsg = UnsuppSASScheme;
523 return NULL;
524 }
525 sasType = cp;
526
527 // dhContext cannot be NULL - always setup during prepareCommit()
Alexandre Lisione24852d2014-02-04 13:13:02 -0500528 // check if we can use the dhContext prepared by prepareCOmmit(),
Alexandre Lision51140e12013-12-02 10:54:09 -0500529 // if not delete old DH context and generate new one
530 // The algorithm names are 4 chars only, thus we can cast to int32_t
531 if (*(int32_t*)(dhContext->getDHtype()) != *(int32_t*)(pubKey->getName())) {
532 delete dhContext;
533 dhContext = new ZrtpDH(pubKey->getName());
534 dhContext->generatePublicKey();
535 }
536 sendInfo(Info, InfoDH1DHGenerated);
537
538 dhContext->getPubKeyBytes(pubKeyBytes);
539
540 // Setup a DHPart1 packet.
541 zrtpDH1.setPubKeyType(pubKey->getName());
542 zrtpDH1.setMessageType((uint8_t*)DHPart1Msg);
543 zrtpDH1.setRs1Id(rs1IDr);
544 zrtpDH1.setRs2Id(rs2IDr);
545 zrtpDH1.setAuxSecretId(auxSecretIDr);
546 zrtpDH1.setPbxSecretId(pbxSecretIDr);
547 zrtpDH1.setPv(pubKeyBytes);
548 zrtpDH1.setH1(H1);
549
550 int32_t len = zrtpDH1.getLength() * ZRTP_WORD_SIZE;
551
552 // Compute HMAC over DHPart1, excluding the HMAC field (HMAC_SIZE)
553 // and store in DHPart1.
554 // Use implicit Hash function
555 uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];
556 uint32_t macLen;
557 hmacFunctionImpl(H0, HASH_IMAGE_SIZE, (uint8_t*)zrtpDH1.getHeaderBase(), len-(HMAC_SIZE), hmac, &macLen);
558 zrtpDH1.setHMAC(hmac);
559
560 // We are definitly responder. Save the peer's hvi for later compare.
Alexandre Lisione24852d2014-02-04 13:13:02 -0500561 myRole = Responder;
Alexandre Lision51140e12013-12-02 10:54:09 -0500562 memcpy(peerHvi, commit->getHvi(), HVI_SIZE);
563
Alexandre Lisione24852d2014-02-04 13:13:02 -0500564 // We are responder. Release a possibly pre-computed SHA context
565 // because this was prepared for Initiator. Then create a new one.
Alexandre Lision51140e12013-12-02 10:54:09 -0500566 if (msgShaContext != NULL) {
567 closeHashCtx(msgShaContext, NULL);
568 }
569 msgShaContext = createHashCtx();
570
571 // Hash messages to produce overall message hash:
Alexandre Lisione24852d2014-02-04 13:13:02 -0500572 // First the Responder's (my) Hello message, second the Commit
573 // (always Initator's), then the DH1 message (which is always a
574 // Responder's message).
575 // Must use negotiated hash
576 hashCtxFunction(msgShaContext, (unsigned char*)zrtpHello.getHeaderBase(), zrtpHello.getLength() * ZRTP_WORD_SIZE);
Alexandre Lision51140e12013-12-02 10:54:09 -0500577 hashCtxFunction(msgShaContext, (unsigned char*)commit->getHeaderBase(), commit->getLength() * ZRTP_WORD_SIZE);
578 hashCtxFunction(msgShaContext, (unsigned char*)zrtpDH1.getHeaderBase(), zrtpDH1.getLength() * ZRTP_WORD_SIZE);
579
580 // store Commit data temporarily until we can check HMAC after we got DHPart2
581 storeMsgTemp(commit);
582
583 return &zrtpDH1;
584}
585
586/*
587 * At this point we will take the role of the Initiator.
588 */
589ZrtpPacketDHPart* ZRtp::prepareDHPart2(ZrtpPacketDHPart *dhPart1, uint32_t* errMsg) {
590
591 uint8_t* pvr;
592
593 sendInfo(Info, InfoInitDH1Received);
594
595 // Because we are initiator the protocol engine didn't receive Commit
596 // thus could not store a peer's H2. A two step SHA256 is required to
597 // re-compute H3. Then compare with peer's H3 from peer's Hello packet.
598 // Must use implicit hash function.
599 uint8_t tmpHash[IMPL_MAX_DIGEST_LENGTH];
600 hashFunctionImpl(dhPart1->getH1(), HASH_IMAGE_SIZE, tmpHash); // Compute peer's H2
601 memcpy(peerH2, tmpHash, HASH_IMAGE_SIZE);
602 hashFunctionImpl(peerH2, HASH_IMAGE_SIZE, tmpHash); // Compute peer's H3 (tmpHash)
603
604 if (memcmp(tmpHash, peerH3, HASH_IMAGE_SIZE) != 0) {
605 *errMsg = IgnorePacket;
606 return NULL;
607 }
608
609 // Check HMAC of previous Hello packet stored in temporary buffer. The
610 // HMAC key of the Hello packet is peer's H2 that was computed above.
611 // Refer to chapter 9.1 and chapter 10.
612 if (!checkMsgHmac(peerH2)) {
613 sendInfo(Severe, SevereHelloHMACFailed);
614 *errMsg = CriticalSWError;
615 return NULL;
616 }
617
618 // get memory to store DH result TODO: make it fixed memory
619 DHss = new uint8_t[dhContext->getDhSize()];
620 if (DHss == NULL) {
621 *errMsg = CriticalSWError;
622 return NULL;
623 }
624
625 // get and check Responder's public value, see chap. 5.4.3 in the spec
626 pvr = dhPart1->getPv();
627 if (!dhContext->checkPubKey(pvr)) {
628 *errMsg = DHErrorWrongPV;
629 return NULL;
630 }
631 dhContext->computeSecretKey(pvr, DHss);
632
Alexandre Lisione24852d2014-02-04 13:13:02 -0500633 myRole = Initiator;
634
Alexandre Lision51140e12013-12-02 10:54:09 -0500635 // We are Initiator: the Responder's Hello and the Initiator's (our) Commit
636 // are already hashed in the context. Now hash the Responder's DH1 and then
637 // the Initiator's (our) DH2 in that order.
638 // Use the negotiated hash function.
639 hashCtxFunction(msgShaContext, (unsigned char*)dhPart1->getHeaderBase(), dhPart1->getLength() * ZRTP_WORD_SIZE);
640 hashCtxFunction(msgShaContext, (unsigned char*)zrtpDH2.getHeaderBase(), zrtpDH2.getLength() * ZRTP_WORD_SIZE);
641
642 // Compute the message Hash
643 closeHashCtx(msgShaContext, messageHash);
644 msgShaContext = NULL;
Alexandre Lisione24852d2014-02-04 13:13:02 -0500645
646 // To compute the keys for the Initiator we need the retained secrets of our
647 // peer. Get them from the storage.
648 ZIDRecord zidRec(peerZid);
649 ZIDFile *zid = ZIDFile::getInstance();
650 zid->getRecord(&zidRec);
651
Alexandre Lision51140e12013-12-02 10:54:09 -0500652 // Now compute the S0, all dependend keys and the new RS1. The function
653 // also performs sign SAS callback if it's active.
654 generateKeysInitiator(dhPart1, zidRec);
Alexandre Lisione24852d2014-02-04 13:13:02 -0500655 zid->saveRecord(&zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -0500656
657 delete dhContext;
658 dhContext = NULL;
659
660 // TODO: at initiator we can call signSAS at this point, don't dealy until confirm1 reveived
661 // store DHPart1 data temporarily until we can check HMAC after receiving Confirm1
662 storeMsgTemp(dhPart1);
663 return &zrtpDH2;
664}
665
666/*
667 * At this point we are Responder.
668 */
669ZrtpPacketConfirm* ZRtp::prepareConfirm1(ZrtpPacketDHPart* dhPart2, uint32_t* errMsg) {
670
671 uint8_t* pvi;
672
673 sendInfo(Info, InfoRespDH2Received);
674
675 // Because we are responder we received a Commit and stored its H2.
676 // Now re-compute H2 from received H1 and compare with stored peer's H2.
677 // Use implicit hash function
678 uint8_t tmpHash[IMPL_MAX_DIGEST_LENGTH];
679 hashFunctionImpl(dhPart2->getH1(), HASH_IMAGE_SIZE, tmpHash);
680 if (memcmp(tmpHash, peerH2, HASH_IMAGE_SIZE) != 0) {
681 *errMsg = IgnorePacket;
682 return NULL;
683 }
684
685 // Check HMAC of Commit packet stored in temporary buffer. The
686 // HMAC key of the Commit packet is peer's H1 that is contained in
687 // DHPart2. Refer to chapter 9.1 and chapter 10.
688 if (!checkMsgHmac(dhPart2->getH1())) {
689 sendInfo(Severe, SevereCommitHMACFailed);
690 *errMsg = CriticalSWError;
691 return NULL;
692 }
693 // Now we have the peer's pvi. Because we are responder re-compute my hvi
694 // using my Hello packet and the Initiator's DHPart2 and compare with
695 // hvi sent in commit packet. If it doesn't macht then a MitM attack
696 // may have occured.
Alexandre Lisione24852d2014-02-04 13:13:02 -0500697 computeHvi(dhPart2, &zrtpHello);
Alexandre Lision51140e12013-12-02 10:54:09 -0500698 if (memcmp(hvi, peerHvi, HVI_SIZE) != 0) {
699 *errMsg = DHErrorWrongHVI;
700 return NULL;
701 }
702 DHss = new uint8_t[dhContext->getDhSize()];
703 if (DHss == NULL) {
704 *errMsg = CriticalSWError;
705 return NULL;
706 }
707 // Get and check the Initiator's public value, see chap. 5.4.2 of the spec
708 pvi = dhPart2->getPv();
709 if (!dhContext->checkPubKey(pvi)) {
710 *errMsg = DHErrorWrongPV;
711 return NULL;
712 }
713 dhContext->computeSecretKey(pvi, DHss);
Alexandre Lisione24852d2014-02-04 13:13:02 -0500714 // Hash the Initiator's DH2 into the message Hash (other messages already
715 // prepared, see method prepareDHPart1().
Alexandre Lision51140e12013-12-02 10:54:09 -0500716 // Use neotiated hash function
717 hashCtxFunction(msgShaContext, (unsigned char*)dhPart2->getHeaderBase(), dhPart2->getLength() * ZRTP_WORD_SIZE);
718
719 closeHashCtx(msgShaContext, messageHash);
720 msgShaContext = NULL;
Alexandre Lisione24852d2014-02-04 13:13:02 -0500721
722 // To compute the Keys for the Initiator we need the retained secrets of our
723 // peer. Get them from the storage.
724 ZIDRecord zidRec(peerZid);
725 ZIDFile *zid = ZIDFile::getInstance();
726 zid->getRecord(&zidRec);
727
Alexandre Lision51140e12013-12-02 10:54:09 -0500728 /*
729 * The expected shared secret Ids were already computed when we built the
730 * DHPart1 packet. Generate s0, all depended keys, and the new RS1 value
Alexandre Lisione24852d2014-02-04 13:13:02 -0500731 * for the ZID record. The functions also performs sign SAS callback if it's active.
Alexandre Lision51140e12013-12-02 10:54:09 -0500732 */
733 generateKeysResponder(dhPart2, zidRec);
Alexandre Lisione24852d2014-02-04 13:13:02 -0500734 zid->saveRecord(&zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -0500735
736 delete dhContext;
737 dhContext = NULL;
738
739 // Fill in Confirm1 packet.
740 zrtpConfirm1.setMessageType((uint8_t*)Confirm1Msg);
741
742 // Check if user verfied the SAS in a previous call and thus verfied
743 // the retained secret. Don't set the verified flag if paranoidMode is true.
Alexandre Lisione24852d2014-02-04 13:13:02 -0500744 if (zidRec.isSasVerified() && !paranoidMode) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500745 zrtpConfirm1.setSASFlag();
746 }
747 zrtpConfirm1.setExpTime(0xFFFFFFFF);
748 zrtpConfirm1.setIv(randomIV);
749 zrtpConfirm1.setHashH0(H0);
750
Alexandre Lisione24852d2014-02-04 13:13:02 -0500751 // if this run at PBX user agent enrollment service then set flag in confirm
Alexandre Lision51140e12013-12-02 10:54:09 -0500752 // packet and store the MitM key
753 if (enrollmentMode) {
Alexandre Lisione24852d2014-02-04 13:13:02 -0500754 computePBXSecret();
Alexandre Lision51140e12013-12-02 10:54:09 -0500755 zrtpConfirm1.setPBXEnrollment();
Alexandre Lisione24852d2014-02-04 13:13:02 -0500756 writeEnrollmentPBX();
Alexandre Lision51140e12013-12-02 10:54:09 -0500757 }
758 uint8_t confMac[MAX_DIGEST_LENGTH];
759 uint32_t macLen;
760
761 // Encrypt and HMAC with Responder's key - we are Respondere here
762 int hmlen = (zrtpConfirm1.getLength() - 9) * ZRTP_WORD_SIZE;
763 cipher->getEncrypt()(zrtpKeyR, cipher->getKeylen(), randomIV, zrtpConfirm1.getHashH0(), hmlen);
764 hmacFunction(hmacKeyR, hashLength, (unsigned char*)zrtpConfirm1.getHashH0(), hmlen, confMac, &macLen);
765
766 zrtpConfirm1.setHmac(confMac);
767
768 // store DHPart2 data temporarily until we can check HMAC after receiving Confirm2
769 storeMsgTemp(dhPart2);
770 return &zrtpConfirm1;
771}
772
773/*
774 * At this point we are Responder.
775 */
776ZrtpPacketConfirm* ZRtp::prepareConfirm1MultiStream(ZrtpPacketCommit* commit, uint32_t* errMsg) {
777
778 sendInfo(Info, InfoRespCommitReceived);
779
780 // The following code checks the hash chain according chapter 10 to detect
781 // false ZRTP packets.
782 // Use implicit hash function
783 uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];
784 memcpy(peerH2, commit->getH2(), HASH_IMAGE_SIZE);
785 hashFunctionImpl(peerH2, HASH_IMAGE_SIZE, tmpH3);
786
787 if (memcmp(tmpH3, peerH3, HASH_IMAGE_SIZE) != 0) {
788 *errMsg = IgnorePacket;
789 return NULL;
790 }
791
792 // Check HMAC of previous Hello packet stored in temporary buffer. The
793 // HMAC key of peer's Hello packet is peer's H2 that is contained in the
794 // Commit packet. Refer to chapter 9.1.
795 if (!checkMsgHmac(peerH2)) {
796 sendInfo(Severe, SevereHelloHMACFailed);
797 *errMsg = CriticalSWError;
798 return NULL;
799 }
800
801 // check if Commit contains "Mult" as pub key type
802 AlgorithmEnum* cp = &zrtpPubKeys.getByName((const char*)commit->getPubKeysType());
803 if (!cp->isValid() || *(int32_t*)(cp->getName()) != *(int32_t*)mult) {
804 *errMsg = UnsuppPKExchange;
805 return NULL;
806 }
807
808 // check if we support the commited cipher
809 cp = &zrtpSymCiphers.getByName((const char*)commit->getCipherType());
810 if (!cp->isValid()) { // no match - something went wrong
811 *errMsg = UnsuppCiphertype;
812 return NULL;
813 }
814 cipher = cp;
815
816 // check if we support the commited Authentication length
817 cp = &zrtpAuthLengths.getByName((const char*)commit->getAuthLen());
818 if (!cp->isValid()) { // no match - something went wrong
819 *errMsg = UnsuppSRTPAuthTag;
820 return NULL;
821 }
822 authLength = cp;
823
824 // check if we support the commited hash type
825 cp = &zrtpHashes.getByName((const char*)commit->getHashType());
826 if (!cp->isValid()) { // no match - something went wrong
827 *errMsg = UnsuppHashType;
828 return NULL;
829 }
830 // check if the peer's commited hash is the same that we used when
831 // preparing our commit packet. If not do the necessary resets and
832 // recompute some data.
833 if (*(int32_t*)(hash->getName()) != *(int32_t*)(cp->getName())) {
834 hash = cp;
835 setNegotiatedHash(hash);
836 }
837 myRole = Responder;
838
839 // We are responder. Release a possibly pre-computed SHA256 context
840 // because this was prepared for Initiator. Then create a new one.
841 if (msgShaContext != NULL) {
842 closeHashCtx(msgShaContext, NULL);
843 }
844 msgShaContext = createHashCtx();
845
846 // Hash messages to produce overall message hash:
847 // First the Responder's (my) Hello message, second the Commit
848 // (always Initator's)
849 // use negotiated hash
Alexandre Lisione24852d2014-02-04 13:13:02 -0500850 hashCtxFunction(msgShaContext, (unsigned char*)zrtpHello.getHeaderBase(), zrtpHello.getLength() * ZRTP_WORD_SIZE);
Alexandre Lision51140e12013-12-02 10:54:09 -0500851 hashCtxFunction(msgShaContext, (unsigned char*)commit->getHeaderBase(), commit->getLength() * ZRTP_WORD_SIZE);
852
853 closeHashCtx(msgShaContext, messageHash);
854 msgShaContext = NULL;
855
856 generateKeysMultiStream();
857
858 // Fill in Confirm1 packet.
859 zrtpConfirm1.setMessageType((uint8_t*)Confirm1Msg);
860 zrtpConfirm1.setExpTime(0xFFFFFFFF);
861 zrtpConfirm1.setIv(randomIV);
862 zrtpConfirm1.setHashH0(H0);
863
864 uint8_t confMac[MAX_DIGEST_LENGTH];
865 uint32_t macLen;
866
867 // Encrypt and HMAC with Responder's key - we are Respondere here
868 int32_t hmlen = (zrtpConfirm1.getLength() - 9) * ZRTP_WORD_SIZE;
869 cipher->getEncrypt()(zrtpKeyR, cipher->getKeylen(), randomIV, zrtpConfirm1.getHashH0(), hmlen);
870
871 // Use negotiated HMAC (hash)
872 hmacFunction(hmacKeyR, hashLength, (unsigned char*)zrtpConfirm1.getHashH0(), hmlen, confMac, &macLen);
873
874 zrtpConfirm1.setHmac(confMac);
875
876 // Store Commit data temporarily until we can check HMAC after receiving Confirm2
877 storeMsgTemp(commit);
878 return &zrtpConfirm1;
879}
880
881/*
882 * At this point we are Initiator.
883 */
884ZrtpPacketConfirm* ZRtp::prepareConfirm2(ZrtpPacketConfirm* confirm1, uint32_t* errMsg) {
885
886 sendInfo(Info, InfoInitConf1Received);
887
888 uint8_t confMac[MAX_DIGEST_LENGTH];
889 uint32_t macLen;
890
891 // Use the Responder's keys here because we are Initiator here and
892 // receive packets from Responder
893 int16_t hmlen = (confirm1->getLength() - 9) * ZRTP_WORD_SIZE;
894
895 // Use negotiated HMAC (hash)
896 hmacFunction(hmacKeyR, hashLength, (unsigned char*)confirm1->getHashH0(), hmlen, confMac, &macLen);
897
898 if (memcmp(confMac, confirm1->getHmac(), HMAC_SIZE) != 0) {
899 *errMsg = ConfirmHMACWrong;
900 return NULL;
901 }
Alexandre Lisione24852d2014-02-04 13:13:02 -0500902 cipher->getDecrypt()(zrtpKeyR, cipher->getKeylen(), confirm1->getIv(), confirm1->getHashH0(), hmlen);
903
904 std::string cs(cipher->getReadable());
905 cs.append("/").append(pubKey->getName());
Alexandre Lision51140e12013-12-02 10:54:09 -0500906
907 // Check HMAC of DHPart1 packet stored in temporary buffer. The
908 // HMAC key of the DHPart1 packet is peer's H0 that is contained in
909 // Confirm1. Refer to chapter 9.
910 if (!checkMsgHmac(confirm1->getHashH0())) {
911 sendInfo(Severe, SevereDH1HMACFailed);
912 *errMsg = CriticalSWError;
913 return NULL;
914 }
915 signatureLength = confirm1->getSignatureLength();
Alexandre Lisione24852d2014-02-04 13:13:02 -0500916 if (signSasSeen && signatureLength > 0) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500917 signatureData = confirm1->getSignatureData();
918 callback->checkSASSignature(sasHash);
919 // TODO: error handling if checkSASSignature returns false.
920 }
921 /*
922 * The Confirm1 is ok, handle the Retained secret stuff and inform
923 * GUI about state.
924 */
925 bool sasFlag = confirm1->isSASFlag();
926
Alexandre Lisione24852d2014-02-04 13:13:02 -0500927 // Initialize a ZID record to get peer's retained secrets
928 ZIDRecord zidRec(peerZid);
929
930 ZIDFile *zid = ZIDFile::getInstance();
931 zid->getRecord(&zidRec);
932
Alexandre Lision51140e12013-12-02 10:54:09 -0500933 // Our peer did not confirm the SAS in last session, thus reset
934 // our SAS flag too. Reset the flag also if paranoidMode is true.
935 if (!sasFlag || paranoidMode) {
Alexandre Lisione24852d2014-02-04 13:13:02 -0500936 zidRec.resetSasVerified();
Alexandre Lision51140e12013-12-02 10:54:09 -0500937 }
938 // get verified flag from current RS1 before set a new RS1. This
939 // may not be set even if peer's flag is set in confirm1 message.
Alexandre Lisione24852d2014-02-04 13:13:02 -0500940 sasFlag = zidRec.isSasVerified();
941
942 callback->srtpSecretsOn(cs, SAS, sasFlag);
Alexandre Lision51140e12013-12-02 10:54:09 -0500943
944 // now we are ready to save the new RS1 which inherits the verified
945 // flag from old RS1
Alexandre Lisione24852d2014-02-04 13:13:02 -0500946 zidRec.setNewRs1((const uint8_t*)newRs1);
947 zid->saveRecord(&zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -0500948
949 // now generate my Confirm2 message
950 zrtpConfirm2.setMessageType((uint8_t*)Confirm2Msg);
951 zrtpConfirm2.setHashH0(H0);
952
953 if (sasFlag) {
954 zrtpConfirm2.setSASFlag();
955 }
956 zrtpConfirm2.setExpTime(0xFFFFFFFF);
957 zrtpConfirm2.setIv(randomIV);
958
959 // Compute PBX secret if we are in enrollemnt mode (PBX user agent)
960 // or enrollment was enabled at normal user agent and flag in confirm packet
961 if (enrollmentMode || (enableMitmEnrollment && confirm1->isPBXEnrollment())) {
962 computePBXSecret();
963
964 // if this runs at PBX user agent enrollment service then set flag in confirm
965 // packet and store the MitM key. The PBX user agent service always stores
966 // its MitM key.
967 if (enrollmentMode) {
968 zrtpConfirm2.setPBXEnrollment();
Alexandre Lisione24852d2014-02-04 13:13:02 -0500969 writeEnrollmentPBX();
Alexandre Lision51140e12013-12-02 10:54:09 -0500970 }
971 }
972 // Encrypt and HMAC with Initiator's key - we are Initiator here
973 hmlen = (zrtpConfirm2.getLength() - 9) * ZRTP_WORD_SIZE;
974 cipher->getEncrypt()(zrtpKeyI, cipher->getKeylen(), randomIV, zrtpConfirm2.getHashH0(), hmlen);
975
976 // Use negotiated HMAC (hash)
977 hmacFunction(hmacKeyI, hashLength, (unsigned char*)zrtpConfirm2.getHashH0(), hmlen, confMac, &macLen);
978
979 zrtpConfirm2.setHmac(confMac);
980
981 // Ask for enrollment only if enabled via configuration and the
982 // confirm1 packet contains the enrollment flag. The enrolling user
983 // agent stores the MitM key only if the user accepts the enrollment
984 // request.
985 if (enableMitmEnrollment && confirm1->isPBXEnrollment()) {
Alexandre Lisione24852d2014-02-04 13:13:02 -0500986 callback->zrtpAskEnrollment(EnrollmentRequest);
Alexandre Lision51140e12013-12-02 10:54:09 -0500987 }
988 return &zrtpConfirm2;
989}
990
Alexandre Lisione24852d2014-02-04 13:13:02 -0500991/**
992 * Save the computed MitM secret to the ZID record of the peer
993 */
994void ZRtp::writeEnrollmentPBX() {
995 // Initialize a ZID record to get peer's retained secrets
996 ZIDRecord zidRec(peerZid);
997
998 ZIDFile *zid = ZIDFile::getInstance();
999 zid->getRecord(&zidRec);
1000
1001 if (pbxSecretTmp != NULL) {
1002 zidRec.setMiTMData(pbxSecretTmp);
1003 }
1004 zid->saveRecord(&zidRec);
1005}
1006
Alexandre Lision51140e12013-12-02 10:54:09 -05001007/*
1008 * At this point we are Initiator.
1009 */
1010ZrtpPacketConfirm* ZRtp::prepareConfirm2MultiStream(ZrtpPacketConfirm* confirm1, uint32_t* errMsg) {
1011
1012 // check Confirm1 packet using the keys
1013 // prepare Confirm2 packet
1014 // don't update SAS, RS
1015 sendInfo(Info, InfoInitConf1Received);
1016
1017 uint8_t confMac[MAX_DIGEST_LENGTH];
1018 uint32_t macLen;
1019
1020 closeHashCtx(msgShaContext, messageHash);
1021 msgShaContext = NULL;
1022 myRole = Initiator;
1023
1024 generateKeysMultiStream();
1025
1026 // Use the Responder's keys here because we are Initiator here and
1027 // receive packets from Responder
1028 int32_t hmlen = (confirm1->getLength() - 9) * ZRTP_WORD_SIZE;
1029
1030 // Use negotiated HMAC (hash)
1031 hmacFunction(hmacKeyR, hashLength, (unsigned char*)confirm1->getHashH0(), hmlen, confMac, &macLen);
1032
1033 if (memcmp(confMac, confirm1->getHmac(), HMAC_SIZE) != 0) {
1034 *errMsg = ConfirmHMACWrong;
1035 return NULL;
1036 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001037 cipher->getDecrypt()(zrtpKeyR, cipher->getKeylen(), confirm1->getIv(), confirm1->getHashH0(), hmlen);
1038 std::string cs(cipher->getReadable());
Alexandre Lision51140e12013-12-02 10:54:09 -05001039
1040 // Because we are initiator the protocol engine didn't receive Commit and
1041 // because we are using multi-stream mode here we also did not receive a DHPart1 and
1042 // thus could not store a responder's H2 or H1. A two step hash is required to
1043 // re-compute H1, H2.
1044 // USe implicit hash function.
1045 uint8_t tmpHash[IMPL_MAX_DIGEST_LENGTH];
1046 hashFunctionImpl(confirm1->getHashH0(), HASH_IMAGE_SIZE, tmpHash); // Compute peer's H1 in tmpHash
1047 hashFunctionImpl(tmpHash, HASH_IMAGE_SIZE, tmpHash); // Compute peer's H2 in tmpHash
1048 memcpy(peerH2, tmpHash, HASH_IMAGE_SIZE); // copy and truncate to peerH2
1049
1050 // Check HMAC of previous Hello packet stored in temporary buffer. The
1051 // HMAC key of the Hello packet is peer's H2 that was computed above.
1052 // Refer to chapter 9.1 and chapter 10.
1053 if (!checkMsgHmac(peerH2)) {
1054 sendInfo(Severe, SevereHelloHMACFailed);
1055 *errMsg = CriticalSWError;
1056 return NULL;
1057 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001058 // TODO: here we have a SAS signature from reponder, call checkSASsignature (save / compare in case of resend)
1059
1060 // Inform GUI about security state, don't show SAS and its state
1061 std::string cs1("");
1062 callback->srtpSecretsOn(cs, cs1, true);
1063
Alexandre Lision51140e12013-12-02 10:54:09 -05001064 // now generate my Confirm2 message
1065 zrtpConfirm2.setMessageType((uint8_t*)Confirm2Msg);
1066 zrtpConfirm2.setHashH0(H0);
1067 zrtpConfirm2.setExpTime(0xFFFFFFFF);
1068 zrtpConfirm2.setIv(randomIV);
1069
1070 // Encrypt and HMAC with Initiator's key - we are Initiator here
1071 hmlen = (zrtpConfirm2.getLength() - 9) * ZRTP_WORD_SIZE;
1072 cipher->getEncrypt()(zrtpKeyI, cipher->getKeylen(), randomIV, zrtpConfirm2.getHashH0(), hmlen);
1073
1074 // Use negotiated HMAC (hash)
1075 hmacFunction(hmacKeyI, hashLength, (unsigned char*)zrtpConfirm2.getHashH0(), hmlen, confMac, &macLen);
1076
1077 zrtpConfirm2.setHmac(confMac);
1078 return &zrtpConfirm2;
1079}
1080
1081/*
1082 * At this point we are Responder.
1083 */
1084ZrtpPacketConf2Ack* ZRtp::prepareConf2Ack(ZrtpPacketConfirm *confirm2, uint32_t* errMsg) {
1085
1086 sendInfo(Info, InfoRespConf2Received);
1087
1088 uint8_t confMac[MAX_DIGEST_LENGTH];
1089 uint32_t macLen;
1090
1091 // Use the Initiator's keys here because we are Responder here and
1092 // reveice packets from Initiator
1093 int16_t hmlen = (confirm2->getLength() - 9) * ZRTP_WORD_SIZE;
1094
1095 // Use negotiated HMAC (hash)
1096 hmacFunction(hmacKeyI, hashLength,
1097 (unsigned char*)confirm2->getHashH0(),
1098 hmlen, confMac, &macLen);
1099
1100 if (memcmp(confMac, confirm2->getHmac(), HMAC_SIZE) != 0) {
1101 *errMsg = ConfirmHMACWrong;
1102 return NULL;
1103 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001104 cipher->getDecrypt()(zrtpKeyI, cipher->getKeylen(), confirm2->getIv(), confirm2->getHashH0(), hmlen);
1105
1106 std::string cs(cipher->getReadable());
Alexandre Lision51140e12013-12-02 10:54:09 -05001107
1108 if (!multiStream) {
1109 // Check HMAC of DHPart2 packet stored in temporary buffer. The
1110 // HMAC key of the DHPart2 packet is peer's H0 that is contained in
1111 // Confirm2. Refer to chapter 9.1 and chapter 10.
1112 if (!checkMsgHmac(confirm2->getHashH0())) {
1113 sendInfo(Severe, SevereDH2HMACFailed);
1114 *errMsg = CriticalSWError;
1115 return NULL;
1116 }
1117 signatureLength = confirm2->getSignatureLength();
Alexandre Lisione24852d2014-02-04 13:13:02 -05001118 if (signSasSeen && signatureLength > 0) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001119 signatureData = confirm2->getSignatureData();
1120 callback->checkSASSignature(sasHash);
1121 // TODO: error handling if checkSASSignature returns false.
1122 }
1123 /*
1124 * The Confirm2 is ok, handle the Retained secret stuff and inform
1125 * GUI about state.
1126 */
1127 bool sasFlag = confirm2->isSASFlag();
Alexandre Lisione24852d2014-02-04 13:13:02 -05001128
1129 // Initialize a ZID record to get peer's retained secrets
1130 ZIDRecord zidRec(peerZid);
1131
1132 ZIDFile *zid = ZIDFile::getInstance();
1133 zid->getRecord(&zidRec);
1134
Alexandre Lision51140e12013-12-02 10:54:09 -05001135 // Our peer did not confirm the SAS in last session, thus reset
1136 // our SAS flag too. Reset the flag also if paranoidMode is true.
1137 if (!sasFlag || paranoidMode) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05001138 zidRec.resetSasVerified();
Alexandre Lision51140e12013-12-02 10:54:09 -05001139 }
1140
Alexandre Lisione24852d2014-02-04 13:13:02 -05001141 // Now get the resulting SAS verified flag from current RS1 before setting a new RS1.
1142 // It's a combination of our SAS verfied flag and peer's verified flag. Only if both
1143 // were set (true) then sasFlag becomes true.
1144 sasFlag = zidRec.isSasVerified();
1145 cs.append("/").append(pubKey->getName());
1146 callback->srtpSecretsOn(cs, SAS, sasFlag);
1147
Alexandre Lision51140e12013-12-02 10:54:09 -05001148 // save new RS1, this inherits the verified flag from old RS1
Alexandre Lisione24852d2014-02-04 13:13:02 -05001149 zidRec.setNewRs1((const uint8_t*)newRs1);
1150 zid->saveRecord(&zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -05001151
1152 // Ask for enrollment only if enabled via configuration and the
1153 // confirm packet contains the enrollment flag. The enrolling user
1154 // agent stores the MitM key only if the user accepts the enrollment
1155 // request.
1156 if (enableMitmEnrollment && confirm2->isPBXEnrollment()) {
1157 computePBXSecret();
Alexandre Lisione24852d2014-02-04 13:13:02 -05001158 callback->zrtpAskEnrollment(EnrollmentRequest);
Alexandre Lision51140e12013-12-02 10:54:09 -05001159 }
1160 }
1161 else {
1162 // Check HMAC of Commit packet stored in temporary buffer. The
1163 // HMAC key of the Commit packet is initiator's H1
1164 // use implicit hash function.
1165 uint8_t tmpHash[IMPL_MAX_DIGEST_LENGTH];
1166 hashFunctionImpl(confirm2->getHashH0(), HASH_IMAGE_SIZE, tmpHash); // Compute initiator's H1 in tmpHash
1167
1168 if (!checkMsgHmac(tmpHash)) {
1169 sendInfo(Severe, SevereCommitHMACFailed);
1170 *errMsg = CriticalSWError;
1171 return NULL;
1172 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001173 std::string cs1("");
1174
1175 // Inform GUI about security state, don't show SAS and its state
1176 callback->srtpSecretsOn(cs, cs1, true);
Alexandre Lision51140e12013-12-02 10:54:09 -05001177 }
1178 return &zrtpConf2Ack;
1179}
1180
1181ZrtpPacketErrorAck* ZRtp::prepareErrorAck(ZrtpPacketError* epkt) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05001182 sendInfo(ZrtpError, epkt->getErrorCode() * -1);
Alexandre Lision51140e12013-12-02 10:54:09 -05001183 return &zrtpErrorAck;
1184}
1185
1186ZrtpPacketError* ZRtp::prepareError(uint32_t errMsg) {
1187 zrtpError.setErrorCode(errMsg);
1188 return &zrtpError;
1189}
1190
1191ZrtpPacketPingAck* ZRtp::preparePingAck(ZrtpPacketPing* ppkt) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05001192
Alexandre Lision51140e12013-12-02 10:54:09 -05001193 // Because we do not support ZRTP proxy mode use the truncated ZID.
1194 // If this code shall be used in ZRTP proxy implementation the computation
1195 // of the endpoint hash must be enhanced (see chaps 5.15ff and 5.16)
Alexandre Lisione24852d2014-02-04 13:13:02 -05001196 zrtpPingAck.setLocalEpHash(zid);
Alexandre Lision51140e12013-12-02 10:54:09 -05001197 zrtpPingAck.setRemoteEpHash(ppkt->getEpHash());
1198 zrtpPingAck.setSSRC(peerSSRC);
1199 return &zrtpPingAck;
1200}
1201
1202ZrtpPacketRelayAck* ZRtp::prepareRelayAck(ZrtpPacketSASrelay* srly, uint32_t* errMsg) {
1203 // handle and render SAS relay data only if the peer announced that it is a trusted
1204 // PBX. Don't handle SAS relay in paranoidMode.
1205 if (!mitmSeen || paranoidMode)
1206 return &zrtpRelayAck;
1207
1208 uint8_t* hkey, *ekey;
1209 // If we are responder then the PBX used it's Initiator keys
1210 if (myRole == Responder) {
1211 hkey = hmacKeyI;
1212 ekey = zrtpKeyI;
1213 }
1214 else {
1215 hkey = hmacKeyR;
1216 ekey = zrtpKeyR;
1217 }
1218
1219 uint8_t confMac[MAX_DIGEST_LENGTH];
1220 uint32_t macLen;
1221
Alexandre Lisione24852d2014-02-04 13:13:02 -05001222 // Use the Initiator's keys here because we are Responder here and
1223 // reveice packets from Initiator
Alexandre Lision51140e12013-12-02 10:54:09 -05001224 int16_t hmlen = (srly->getLength() - 9) * ZRTP_WORD_SIZE;
1225
1226 // Use negotiated HMAC (hash)
1227 hmacFunction(hkey, hashLength, (unsigned char*)srly->getFiller(), hmlen, confMac, &macLen);
1228
1229 if (memcmp(confMac, srly->getHmac(), HMAC_SIZE) != 0) {
1230 *errMsg = ConfirmHMACWrong;
1231 return NULL; // TODO - check error handling
1232 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001233 cipher->getDecrypt()(ekey, cipher->getKeylen(), srly->getIv(), (uint8_t*)srly->getFiller(), hmlen);
Alexandre Lision51140e12013-12-02 10:54:09 -05001234
Alexandre Lisione24852d2014-02-04 13:13:02 -05001235 const uint8_t* render = srly->getSas();
Alexandre Lision51140e12013-12-02 10:54:09 -05001236 const uint8_t* newSasHash = srly->getTrustedSas();
Alexandre Lisione24852d2014-02-04 13:13:02 -05001237
Alexandre Lision51140e12013-12-02 10:54:09 -05001238 bool sasHashNull = true;
1239 for (int i = 0; i < HASH_IMAGE_SIZE; i++) {
1240 if (newSasHash[i] != 0) {
1241 sasHashNull = false;
1242 break;
1243 }
1244 }
1245 // Check if new SAS is null or a trusted MitM relationship doesn't exist.
1246 // If this is the case then don't render and don't show the new SAS - use
Alexandre Lisione24852d2014-02-04 13:13:02 -05001247 // the computed SAS hash but we may use a different SAS rendering algorithm to
Alexandre Lision51140e12013-12-02 10:54:09 -05001248 // render the computed SAS.
1249 if (sasHashNull || !peerIsEnrolled) {
1250 newSasHash = sasHash;
1251 }
1252 // If other SAS schemes required - check here and use others
1253 AlgorithmEnum* renderAlgo = &zrtpSasTypes.getByName((const char*)render);
Alexandre Lisione24852d2014-02-04 13:13:02 -05001254 uint8_t sasBytes[4];;
Alexandre Lision51140e12013-12-02 10:54:09 -05001255 if (renderAlgo->isValid()) {
1256 sasBytes[0] = newSasHash[0];
1257 sasBytes[1] = newSasHash[1];
1258 sasBytes[2] = newSasHash[2] & 0xf0;
1259 sasBytes[3] = 0;
1260 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001261 SAS = Base32(sasBytes, 20).getEncoded();
1262 std::string cs(cipher->getReadable());
1263 cs.append("/").append(pubKey->getName()).append("/MitM");
1264
1265 callback->srtpSecretsOn(cs, SAS, false);
Alexandre Lision51140e12013-12-02 10:54:09 -05001266 return &zrtpRelayAck;
1267}
1268
1269// TODO Implement GoClear handling
1270ZrtpPacketClearAck* ZRtp::prepareClearAck(ZrtpPacketGoClear* gpkt) {
1271 sendInfo(Warning, WarningGoClearReceived);
1272 return &zrtpClearAck;
1273}
1274
1275ZrtpPacketGoClear* ZRtp::prepareGoClear(uint32_t errMsg) {
1276 ZrtpPacketGoClear* gclr = &zrtpGoClear;
1277 gclr->clrClearHmac();
1278 return gclr;
1279}
1280
1281/*
1282 * The next functions look up and return a prefered algorithm. These
1283 * functions work as follows:
1284 * - If the Hello packet does not contain an algorithm (number of algorithms
1285* is zero) then return the mandatory algorithm.
1286 * - Build a list of algorithm names and ids from configuration data. If
1287 * the configuration data does not contain a mandatory algorithm append
1288 * the mandatory algorithm to the list and ids.
1289 * - Build a list of algorithm names from the Hello message. If
1290 * the Hello message does not contain a mandatory algorithm append
1291 * the mandatory algorithm to the list.
1292 * - Lookup a matching algorithm. The list built from Hello takes
1293 * precedence in the lookup (indexed by the outermost loop).
1294 *
1295 * This guarantees that we always return a supported alogrithm respecting
1296 * the order of algorithms in the Hello message
1297 *
1298 * The mandatory algorithms are: (internal enums are our prefered algoritms)
1299 * Hash: S256 (SHA 256) (internal enum Sha256)
1300 * Symmetric Cipher: AES1 (AES 128) (internal enum Aes128)
1301 * SRTP Authentication: HS32 and HS80 (32/80 bits) (internal enum AuthLen32)
1302 * Key Agreement: DH3k (3072 Diffie-Helman) (internal enum Dh3072)
1303 *
1304 */
1305AlgorithmEnum* ZRtp::findBestHash(ZrtpPacketHello *hello) {
1306
1307 int i;
1308 int ii;
1309 int numAlgosOffered;
1310 AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+1];
1311
1312 int numAlgosConf;
1313 AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
1314
Alexandre Lisione24852d2014-02-04 13:13:02 -05001315 bool mandatoryFound = false;
1316
Alexandre Lision51140e12013-12-02 10:54:09 -05001317 // If Hello does not contain any hash names return Sha256, its mandatory
1318 int num = hello->getNumHashes();
1319 if (num == 0) {
1320 return &zrtpHashes.getByName(mandatoryHash);
1321 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001322 // Build list of configured hash algorithm names, append mandatory algos
1323 // if necessary.
Alexandre Lision51140e12013-12-02 10:54:09 -05001324 numAlgosConf = configureAlgos.getNumConfiguredAlgos(HashAlgorithm);
1325 for (i = 0; i < numAlgosConf; i++) {
1326 algosConf[i] = &configureAlgos.getAlgoAt(HashAlgorithm, i);
Alexandre Lisione24852d2014-02-04 13:13:02 -05001327 if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatoryHash) {
1328 mandatoryFound = true;
1329 }
1330 }
1331 if (!mandatoryFound) {
1332 algosConf[numAlgosConf++] = &zrtpHashes.getByName(mandatoryHash);
Alexandre Lision51140e12013-12-02 10:54:09 -05001333 }
1334
1335 // Build list of offered known algos in Hello, append mandatory algos if necessary
Alexandre Lisione24852d2014-02-04 13:13:02 -05001336 mandatoryFound = false;
Alexandre Lision51140e12013-12-02 10:54:09 -05001337 for (numAlgosOffered = 0, i = 0; i < num; i++) {
1338 algosOffered[numAlgosOffered] = &zrtpHashes.getByName((const char*)hello->getHashType(i));
1339 if (!algosOffered[numAlgosOffered]->isValid())
1340 continue;
Alexandre Lisione24852d2014-02-04 13:13:02 -05001341 if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatoryHash) {
1342 mandatoryFound = true;
1343 }
1344 }
1345 if (!mandatoryFound) {
1346 algosOffered[numAlgosOffered++] = &zrtpHashes.getByName(mandatoryHash);
Alexandre Lision51140e12013-12-02 10:54:09 -05001347 }
1348
Alexandre Lisione24852d2014-02-04 13:13:02 -05001349 // Lookup offered algos in configured algos. Because of appended
1350 // mandatory algorithms at least one match will happen
Alexandre Lision51140e12013-12-02 10:54:09 -05001351 for (i = 0; i < numAlgosOffered; i++) {
1352 for (ii = 0; ii < numAlgosConf; ii++) {
1353 if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
1354 return algosConf[ii];
1355 }
1356 }
1357 }
1358 return &zrtpHashes.getByName(mandatoryHash);
1359}
1360
1361AlgorithmEnum* ZRtp::findBestCipher(ZrtpPacketHello *hello, AlgorithmEnum* pk) {
1362
1363 int i;
1364 int ii;
1365 int numAlgosOffered;
1366 AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+1];
1367
1368 int numAlgosConf;
1369 AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
1370
Alexandre Lisione24852d2014-02-04 13:13:02 -05001371 bool mandatoryFound = false;
1372
Alexandre Lision51140e12013-12-02 10:54:09 -05001373 int num = hello->getNumCiphers();
1374 if (num == 0 || (*(int32_t*)(pk->getName()) == *(int32_t*)dh2k)) {
1375 return &zrtpSymCiphers.getByName(aes1);
1376 }
1377
Alexandre Lisione24852d2014-02-04 13:13:02 -05001378 // Build list of configured cipher algorithm names, append mandatory algos
1379 // if necessary.
Alexandre Lision51140e12013-12-02 10:54:09 -05001380 numAlgosConf = configureAlgos.getNumConfiguredAlgos(CipherAlgorithm);
1381 for (i = 0; i < numAlgosConf; i++) {
1382 algosConf[i] = &configureAlgos.getAlgoAt(CipherAlgorithm, i);
Alexandre Lisione24852d2014-02-04 13:13:02 -05001383 if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatoryCipher) {
1384 mandatoryFound = true;
1385 }
Alexandre Lision51140e12013-12-02 10:54:09 -05001386 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001387 if (!mandatoryFound) {
1388 algosConf[numAlgosConf++] = &zrtpSymCiphers.getByName(mandatoryCipher);
1389 }
1390
1391 // Build list of offered known algos names in Hello, append mandatory algos if
1392 // necessary
1393 mandatoryFound = false;
Alexandre Lision51140e12013-12-02 10:54:09 -05001394 for (numAlgosOffered = 0, i = 0; i < num; i++) {
1395 algosOffered[numAlgosOffered] = &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));
1396 if (!algosOffered[numAlgosOffered]->isValid())
1397 continue;
Alexandre Lisione24852d2014-02-04 13:13:02 -05001398 if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatoryCipher) {
1399 mandatoryFound = true;
1400 }
Alexandre Lision51140e12013-12-02 10:54:09 -05001401 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001402
1403 if (!mandatoryFound) {
1404 algosOffered[numAlgosOffered++] = &zrtpSymCiphers.getByName(mandatoryCipher);
1405 }
1406
1407 // Lookup offered algos in configured algos. Because of appended
1408 // mandatory algorithms at least one match will happen
Alexandre Lision51140e12013-12-02 10:54:09 -05001409 for (i = 0; i < numAlgosOffered; i++) {
1410 for (ii = 0; ii < numAlgosConf; ii++) {
1411 if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
1412 return algosConf[ii];
1413 }
1414 }
1415 }
1416 return &zrtpSymCiphers.getByName(mandatoryCipher);
1417}
1418
1419AlgorithmEnum* ZRtp::findBestPubkey(ZrtpPacketHello *hello) {
1420
Alexandre Lisione24852d2014-02-04 13:13:02 -05001421 int i;
1422 int ii;
1423 int numAlgosOffered;
1424 AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+1];
Alexandre Lision51140e12013-12-02 10:54:09 -05001425
Alexandre Lisione24852d2014-02-04 13:13:02 -05001426 int numAlgosConf;
1427 AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
Alexandre Lision51140e12013-12-02 10:54:09 -05001428
Alexandre Lisione24852d2014-02-04 13:13:02 -05001429 bool mandatoryFound = false;
1430
1431 int num = hello->getNumPubKeys();
1432 if (num == 0) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001433 return &zrtpPubKeys.getByName(mandatoryPubKey);
1434 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001435 // Build list of configured pubkey algorithm names, append mandatory algos
1436 // if necessary.
1437 // The list must include real public key algorithms only, so skip
1438 // mult-stream mode, preshared and alike.
1439 numAlgosConf = configureAlgos.getNumConfiguredAlgos(PubKeyAlgorithm);
1440 for (i = 0, ii = 0; i < numAlgosConf; i++) {
1441 algosConf[ii] = &configureAlgos.getAlgoAt(PubKeyAlgorithm, ii);
1442 if (*(int32_t*)(algosConf[ii]->getName()) == *(int32_t*)mult) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001443 continue; // skip multi-stream mode
1444 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001445 if (*(int32_t*)(algosConf[ii++]->getName()) == *(int32_t*)mandatoryPubKey) {
1446 mandatoryFound = true;
1447 }
1448 }
1449
1450 numAlgosConf = ii;
1451 if (!mandatoryFound) {
1452 algosConf[numAlgosConf++] = &zrtpPubKeys.getByName(mandatoryPubKey);
1453 }
1454
1455 // Build list of offered known algos in Hello, append mandatory algos if necessary
1456 mandatoryFound = false;
1457 for (numAlgosOffered = 0, i = 0; i < num; i++) {
1458 algosOffered[numAlgosOffered] = &zrtpPubKeys.getByName((const char*)hello->getPubKeyType(i));
1459 if (!algosOffered[numAlgosOffered]->isValid())
1460 continue;
1461 if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatoryPubKey) {
1462 mandatoryFound = true;
1463 }
1464 }
1465
1466 if (!mandatoryFound) {
1467 algosOffered[numAlgosOffered++] = &zrtpPubKeys.getByName(mandatoryPubKey);
1468 }
1469
1470 // Lookup offered algos in configured algos. Because of appended
1471 // mandatory algorithms at least one match will happen
1472 for (i = 0; i < numAlgosOffered; i++) {
1473 for (ii = 0; ii < numAlgosConf; ii++) {
1474 if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
1475 return algosConf[ii];
Alexandre Lision51140e12013-12-02 10:54:09 -05001476 }
1477 }
1478 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001479 return &zrtpPubKeys.getByName(mandatoryPubKey);
Alexandre Lision51140e12013-12-02 10:54:09 -05001480}
1481
1482AlgorithmEnum* ZRtp::findBestSASType(ZrtpPacketHello *hello) {
1483
1484 int i;
1485 int ii;
1486 int numAlgosOffered;
1487 AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+1];
1488
1489 int numAlgosConf;
1490 AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
1491
Alexandre Lisione24852d2014-02-04 13:13:02 -05001492 bool mandatoryFound = false;
1493
Alexandre Lision51140e12013-12-02 10:54:09 -05001494 int num = hello->getNumSas();
1495 if (num == 0) {
1496 return &zrtpSasTypes.getByName(mandatorySasType);
1497 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001498 // Buildlist of configured SAS algorithm names, append mandatory algos
1499 // if necessary.
Alexandre Lision51140e12013-12-02 10:54:09 -05001500 numAlgosConf = configureAlgos.getNumConfiguredAlgos(SasType);
1501 for (i = 0; i < numAlgosConf; i++) {
1502 algosConf[i] = &configureAlgos.getAlgoAt(SasType, i);
Alexandre Lisione24852d2014-02-04 13:13:02 -05001503 if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatorySasType) {
1504 mandatoryFound = true;
1505 }
Alexandre Lision51140e12013-12-02 10:54:09 -05001506 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001507
1508 if (!mandatoryFound) {
1509 algosConf[numAlgosConf++] = &zrtpSasTypes.getByName(mandatorySasType);
1510 }
1511
1512 // Build list of offered known algos in Hello, append mandatory algos if necessary
Alexandre Lision51140e12013-12-02 10:54:09 -05001513 for (numAlgosOffered = 0, i = 0; i < num; i++) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05001514 algosOffered[numAlgosOffered] = &zrtpSasTypes.getByName((const char*)hello->getSasType(i++));
Alexandre Lision51140e12013-12-02 10:54:09 -05001515 if (!algosOffered[numAlgosOffered]->isValid())
1516 continue;
Alexandre Lisione24852d2014-02-04 13:13:02 -05001517 if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatorySasType) {
1518 mandatoryFound = true;
1519 }
Alexandre Lision51140e12013-12-02 10:54:09 -05001520 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001521
1522 if (!mandatoryFound) {
1523 algosOffered[numAlgosOffered++] = &zrtpSasTypes.getByName(mandatorySasType);
1524 }
1525
1526 // Lookup offered algos in configured algos. Because of appended
1527 // mandatory algorithms at least one match will happen
Alexandre Lision51140e12013-12-02 10:54:09 -05001528 for (i = 0; i < numAlgosOffered; i++) {
1529 for (ii = 0; ii < numAlgosConf; ii++) {
1530 if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
1531 return algosConf[ii];
1532 }
1533 }
1534 }
1535 return &zrtpSasTypes.getByName(mandatorySasType);
1536}
1537
1538AlgorithmEnum* ZRtp::findBestAuthLen(ZrtpPacketHello *hello) {
1539
1540 int i;
1541 int ii;
1542 int numAlgosOffered;
1543 AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+2];
1544
1545 int numAlgosConf;
1546 AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+2];
1547
Alexandre Lisione24852d2014-02-04 13:13:02 -05001548 bool mandatoryFound_1 = false;
1549 bool mandatoryFound_2 = false;
1550
Alexandre Lision51140e12013-12-02 10:54:09 -05001551 int num = hello->getNumAuth();
1552 if (num == 0) {
1553 return &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
1554 }
1555
Alexandre Lisione24852d2014-02-04 13:13:02 -05001556 // Build list of configured SAS algorithm names, append mandatory algos
1557 // if necessary.
Alexandre Lision51140e12013-12-02 10:54:09 -05001558 numAlgosConf = configureAlgos.getNumConfiguredAlgos(AuthLength);
1559 for (i = 0; i < numAlgosConf; i++) {
1560 algosConf[i] = &configureAlgos.getAlgoAt(AuthLength, i);
Alexandre Lisione24852d2014-02-04 13:13:02 -05001561 if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatoryAuthLen_1) {
1562 mandatoryFound_1 = true;
1563 }
1564 if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatoryAuthLen_2) {
1565 mandatoryFound_2 = true;
1566 }
Alexandre Lision51140e12013-12-02 10:54:09 -05001567 }
1568
Alexandre Lisione24852d2014-02-04 13:13:02 -05001569 if (!mandatoryFound_1) {
1570 algosConf[numAlgosConf++] = &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
1571 }
1572
1573 if (!mandatoryFound_2) {
1574 algosConf[numAlgosConf++] = &zrtpAuthLengths.getByName(mandatoryAuthLen_2);
1575 }
1576
1577 // Build list of offered known algos in Hello, append mandatory algos if necessary
Alexandre Lision51140e12013-12-02 10:54:09 -05001578 for (numAlgosOffered = 0, i = 0; i < num; i++) {
1579 algosOffered[numAlgosOffered] = &zrtpAuthLengths.getByName((const char*)hello->getAuthLen(i));
1580 if (!algosOffered[numAlgosOffered]->isValid())
1581 continue;
Alexandre Lisione24852d2014-02-04 13:13:02 -05001582 if (*(int32_t*)(algosOffered[numAlgosOffered]->getName()) == *(int32_t*)mandatoryAuthLen_1) {
1583 mandatoryFound_1 = true;
1584 }
1585 if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatoryAuthLen_2) {
1586 mandatoryFound_2 = true;
1587 }
Alexandre Lision51140e12013-12-02 10:54:09 -05001588 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001589 if (!mandatoryFound_1) {
1590 algosOffered[numAlgosOffered++] = &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
1591 }
1592 if (!mandatoryFound_2) {
1593 algosOffered[numAlgosOffered++] = &zrtpAuthLengths.getByName(mandatoryAuthLen_2);
1594 }
1595 // Lookup offered algos in configured algos. Because of appended
1596 // mandatory algorithms at least one match will happen
Alexandre Lision51140e12013-12-02 10:54:09 -05001597 for (i = 0; i < numAlgosOffered; i++) {
1598 for (ii = 0; ii < numAlgosConf; ii++) {
1599 if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
1600 return algosConf[ii];
1601 }
1602 }
1603 }
1604 return &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
1605}
1606
1607bool ZRtp::checkMultiStream(ZrtpPacketHello *hello) {
1608
1609 int i;
1610 int num = hello->getNumPubKeys();
1611
1612 // Multi Stream mode is mandatory, thus if nothing is offered then it is supported :-)
1613 if (num == 0) {
1614 return true;
1615 }
1616 for (i = 0; i < num; i++) {
1617 if (*(int32_t*)(hello->getPubKeyType(i)) == *(int32_t*)mult) {
1618 return true;
1619 }
1620 }
1621 return false;
1622}
1623
1624bool ZRtp::verifyH2(ZrtpPacketCommit *commit) {
1625 uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];
1626
1627 sha256(commit->getH2(), HASH_IMAGE_SIZE, tmpH3);
1628 if (memcmp(tmpH3, peerH3, HASH_IMAGE_SIZE) != 0) {
1629 return false;
1630 }
1631 return true;
1632}
1633
1634void ZRtp::computeHvi(ZrtpPacketDHPart* dh, ZrtpPacketHello *hello) {
1635
1636 unsigned char* data[3];
1637 unsigned int length[3];
1638 /*
1639 * populate the vector to compute the HVI hash according to the
1640 * ZRTP specification.
1641 */
1642 data[0] = (uint8_t*)dh->getHeaderBase();
1643 length[0] = dh->getLength() * ZRTP_WORD_SIZE;
1644
1645 data[1] = (uint8_t*)hello->getHeaderBase();
1646 length[1] = hello->getLength() * ZRTP_WORD_SIZE;
1647
1648 data[2] = NULL; // terminate data chunks
1649 hashListFunction(data, length, hvi);
1650 return;
1651}
1652
Alexandre Lisione24852d2014-02-04 13:13:02 -05001653void ZRtp:: computeSharedSecretSet(ZIDRecord &zidRec) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001654
1655 /*
1656 * Compute the Initiator's and Reponder's retained shared secret Ids.
1657 * Use negotiated HMAC.
1658 */
1659 uint8_t randBuf[RS_LENGTH];
1660 uint32_t macLen;
1661
Alexandre Lisione24852d2014-02-04 13:13:02 -05001662 if (!zidRec.isRs1Valid()) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001663 randomZRTP(randBuf, RS_LENGTH);
1664 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs1IDi, &macLen);
1665 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), rs1IDr, &macLen);
1666 }
1667 else {
1668 rs1Valid = true;
Alexandre Lisione24852d2014-02-04 13:13:02 -05001669 hmacFunction((unsigned char*)zidRec.getRs1(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs1IDi, &macLen);
1670 hmacFunction((unsigned char*)zidRec.getRs1(), RS_LENGTH, (unsigned char*)responder, strlen(responder), rs1IDr, &macLen);
Alexandre Lision51140e12013-12-02 10:54:09 -05001671 }
1672
Alexandre Lisione24852d2014-02-04 13:13:02 -05001673 if (!zidRec.isRs2Valid()) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001674 randomZRTP(randBuf, RS_LENGTH);
1675 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs2IDi, &macLen);
1676 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), rs2IDr, &macLen);
1677 }
1678 else {
1679 rs2Valid = true;
Alexandre Lisione24852d2014-02-04 13:13:02 -05001680 hmacFunction((unsigned char*)zidRec.getRs2(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs2IDi, &macLen);
1681 hmacFunction((unsigned char*)zidRec.getRs2(), RS_LENGTH, (unsigned char*)responder, strlen(responder), rs2IDr, &macLen);
Alexandre Lision51140e12013-12-02 10:54:09 -05001682 }
1683
Alexandre Lisione24852d2014-02-04 13:13:02 -05001684 /*
1685 * For the time being we don't support this types of shared secrect. Could be
1686 * easily done: somebody sets some data into our ZRtp object, check it here
1687 * and use it. Otherwise use the random data.
1688 */
1689 randomZRTP(randBuf, RS_LENGTH);
1690 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), auxSecretIDi, &macLen);
1691 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), auxSecretIDr, &macLen);
1692
1693 if (!zidRec.isMITMKeyAvailable()) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001694 randomZRTP(randBuf, RS_LENGTH);
1695 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), pbxSecretIDi, &macLen);
1696 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), pbxSecretIDr, &macLen);
1697 }
1698 else {
Alexandre Lisione24852d2014-02-04 13:13:02 -05001699 hmacFunction((unsigned char*)zidRec.getMiTMData(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), pbxSecretIDi, &macLen);
1700 hmacFunction((unsigned char*)zidRec.getMiTMData(), RS_LENGTH, (unsigned char*)responder, strlen(responder), pbxSecretIDr, &macLen);
Alexandre Lision907ed2e2014-02-04 10:33:09 -05001701 }
Alexandre Lision51140e12013-12-02 10:54:09 -05001702}
1703
1704/*
1705 * The DH packet for this function is DHPart1 and contains the Responder's
1706 * retained secret ids. Compare them with the expected secret ids (refer
1707 * to chapter 5.3 in the specification).
1708 * When using this method then we are in Initiator role.
1709 */
Alexandre Lisione24852d2014-02-04 13:13:02 -05001710void ZRtp::generateKeysInitiator(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001711 const uint8_t* setD[3];
1712 int32_t rsFound = 0;
1713
1714 setD[0] = setD[1] = setD[2] = NULL;
1715
1716 /*
1717 * Select the real secrets into setD. The dhPart is DHpart1 message
1718 * received from responder. rs1IDr and rs2IDr are the expected ids using
1719 * the initator's cached retained secrets.
1720 */
Alexandre Lisione24852d2014-02-04 13:13:02 -05001721 int matchingSecrets = 0;
Alexandre Lision51140e12013-12-02 10:54:09 -05001722 if (memcmp(rs1IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05001723 setD[matchingSecrets++] = zidRec.getRs1();
Alexandre Lision51140e12013-12-02 10:54:09 -05001724 rsFound = 0x1;
1725 }
1726 else if (memcmp(rs1IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05001727 setD[matchingSecrets++] = zidRec.getRs1();
Alexandre Lision51140e12013-12-02 10:54:09 -05001728 rsFound = 0x2;
1729 }
1730 else if (memcmp(rs2IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05001731 setD[matchingSecrets++] = zidRec.getRs2();
Alexandre Lision51140e12013-12-02 10:54:09 -05001732 rsFound = 0x4;
1733 }
1734 else if (memcmp(rs2IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05001735 setD[matchingSecrets++] = zidRec.getRs2();
Alexandre Lision51140e12013-12-02 10:54:09 -05001736 rsFound = 0x8;
1737 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001738 /* *** Not yet supported
Alexandre Lision51140e12013-12-02 10:54:09 -05001739 if (memcmp(auxSecretIDr, dhPart->getAuxSecretId(), 8) == 0) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05001740 DEBUGOUT((fprintf(stdout, "%c: Match for aux secret found\n", zid[0])));
1741 setD[matchingSecrets++] = auxSecret;
Alexandre Lision51140e12013-12-02 10:54:09 -05001742 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001743 */
1744 if (memcmp(pbxSecretIDr, dhPart->getPbxSecretId(), 8) == 0) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001745 DEBUGOUT((fprintf(stdout, "%c: Match for Other_secret found\n", zid[0])));
Alexandre Lisione24852d2014-02-04 13:13:02 -05001746 setD[matchingSecrets++] = zidRec.getMiTMData();
Alexandre Lision51140e12013-12-02 10:54:09 -05001747 }
1748 // Check if some retained secrets found
1749 if (rsFound == 0) { // no RS matches found
1750 if (rs1Valid || rs2Valid) { // but valid RS records in cache
1751 sendInfo(Warning, WarningNoExpectedRSMatch);
Alexandre Lisione24852d2014-02-04 13:13:02 -05001752 zidRec.resetSasVerified();
Alexandre Lision51140e12013-12-02 10:54:09 -05001753 }
1754 else { // No valid RS record in cache
1755 sendInfo(Warning, WarningNoRSMatch);
1756 }
1757 }
1758 else { // at least one RS matches
1759 sendInfo(Info, InfoRSMatchFound);
1760 }
1761 /*
1762 * Ready to generate s0 here.
1763 * The formular to compute S0 (Refer to ZRTP specification 5.4.4):
1764 *
1765 s0 = hash( counter | DHResult | "ZRTP-HMAC-KDF" | ZIDi | ZIDr | \
1766 total_hash | len(s1) | s1 | len(s2) | s2 | len(s3) | s3)
1767 *
1768 * Note: in this function we are Initiator, thus ZIDi is our zid
1769 * (zid), ZIDr is the peer's zid (peerZid).
1770 */
1771
1772 /*
1773 * These arrays hold the pointers and lengths of the data that must be
1774 * hashed to create S0. According to the formula the max number of
1775 * elements to hash is 12, add one for the terminating "NULL"
1776 */
1777 unsigned char* data[13];
1778 unsigned int length[13];
1779 uint32_t pos = 0; // index into the array
1780
1781 // we need a number of length data items, so define them here
1782 uint32_t counter, sLen[3];
1783
1784 //Very first element is a fixed counter, big endian
1785 counter = 1;
Alexandre Lisione24852d2014-02-04 13:13:02 -05001786 counter = htonl(counter);
Alexandre Lision51140e12013-12-02 10:54:09 -05001787 data[pos] = (unsigned char*)&counter;
1788 length[pos++] = sizeof(uint32_t);
1789
1790 // Next is the DH result itself
1791 data[pos] = DHss;
1792 length[pos++] = dhContext->getDhSize();
1793
1794 // Next the fixed string "ZRTP-HMAC-KDF"
1795 data[pos] = (unsigned char*)KDFString;
1796 length[pos++] = strlen(KDFString);
1797
1798 // Next is Initiator's id (ZIDi), in this case as Initiator
1799 // it is zid
Alexandre Lisione24852d2014-02-04 13:13:02 -05001800 data[pos] = zid;
Alexandre Lision51140e12013-12-02 10:54:09 -05001801 length[pos++] = ZID_SIZE;
1802
1803 // Next is Responder's id (ZIDr), in this case our peer's id
1804 data[pos] = peerZid;
1805 length[pos++] = ZID_SIZE;
1806
1807 // Next ist total hash (messageHash) itself
1808 data[pos] = messageHash;
1809 length[pos++] = hashLength;
1810
1811 /*
1812 * For each matching shared secret hash the length of
1813 * the shared secret as 32 bit big-endian number followd by the
1814 * shared secret itself. The length of a shared seceret is
1815 * currently fixed to RS_LENGTH. If a shared
1816 * secret is not used _only_ its length is hased as zero
1817 * length. NOTE: if implementing auxSecret and/or pbxSecret -> check
1818 * this length stuff again.
1819 */
1820 int secretHashLen = RS_LENGTH;
Alexandre Lisione24852d2014-02-04 13:13:02 -05001821 secretHashLen = htonl(secretHashLen); // prepare 32 bit big-endian number
Alexandre Lision51140e12013-12-02 10:54:09 -05001822
1823 for (int32_t i = 0; i < 3; i++) {
1824 if (setD[i] != NULL) { // a matching secret, set length, then secret
1825 sLen[i] = secretHashLen;
1826 data[pos] = (unsigned char*)&sLen[i];
1827 length[pos++] = sizeof(uint32_t);
1828 data[pos] = (unsigned char*)setD[i];
Alexandre Lisione24852d2014-02-04 13:13:02 -05001829 length[pos++] = RS_LENGTH;
Alexandre Lision51140e12013-12-02 10:54:09 -05001830 }
1831 else { // no machting secret, set length 0, skip secret
1832 sLen[i] = 0;
1833 data[pos] = (unsigned char*)&sLen[i];
1834 length[pos++] = sizeof(uint32_t);
1835 }
1836 }
1837
1838 data[pos] = NULL;
1839 hashListFunction(data, length, s0);
1840// hexdump("S0 I", s0, hashLength);
1841
1842 memset(DHss, 0, dhContext->getDhSize());
1843 delete[] DHss;
1844 DHss = NULL;
1845
1846 computeSRTPKeys();
1847 memset(s0, 0, MAX_DIGEST_LENGTH);
1848}
1849/*
1850 * The DH packet for this function is DHPart2 and contains the Initiator's
1851 * retained secret ids. Compare them with the expected secret ids (refer
1852 * to chapter 5.3.1 in the specification).
1853 */
Alexandre Lisione24852d2014-02-04 13:13:02 -05001854void ZRtp::generateKeysResponder(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001855 const uint8_t* setD[3];
1856 int32_t rsFound = 0;
1857
1858 setD[0] = setD[1] = setD[2] = NULL;
1859
1860 /*
1861 * Select the real secrets into setD
1862 */
Alexandre Lisione24852d2014-02-04 13:13:02 -05001863 int matchingSecrets = 0;
Alexandre Lision51140e12013-12-02 10:54:09 -05001864 if (memcmp(rs1IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05001865 setD[matchingSecrets++] = zidRec.getRs1();
Alexandre Lision51140e12013-12-02 10:54:09 -05001866 rsFound = 0x1;
1867 }
1868 else if (memcmp(rs1IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05001869 setD[matchingSecrets++] = zidRec.getRs1();
Alexandre Lision51140e12013-12-02 10:54:09 -05001870 rsFound = 0x2;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001871 }
1872 else if (memcmp(rs2IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05001873 setD[matchingSecrets++] = zidRec.getRs2();
1874 rsFound |= 0x4;
1875 }
1876 else if (memcmp(rs2IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
1877 setD[matchingSecrets++] = zidRec.getRs2();
Alexandre Lision51140e12013-12-02 10:54:09 -05001878 rsFound |= 0x8;
1879 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001880 /* ***** not yet supported
1881 if (memcmp(auxSecretIDi, dhPart->getauxSecretId(), 8) == 0) {
1882 DEBUGOUT((fprintf(stdout, "%c: Match for aux secret found\n", zid[0])));
1883 setD[matchingSecrets++] = ;
Alexandre Lision51140e12013-12-02 10:54:09 -05001884 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05001885 */
Alexandre Lision51140e12013-12-02 10:54:09 -05001886 if (memcmp(pbxSecretIDi, dhPart->getPbxSecretId(), 8) == 0) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05001887 DEBUGOUT((fprintf(stdout, "%c: Match for PBX secret found\n", zid[0])));
1888 setD[matchingSecrets++] = zidRec.getMiTMData();
Alexandre Lision51140e12013-12-02 10:54:09 -05001889 }
1890 // Check if some retained secrets found
1891 if (rsFound == 0) { // no RS matches found
1892 if (rs1Valid || rs2Valid) { // but valid RS records in cache
1893 sendInfo(Warning, WarningNoExpectedRSMatch);
Alexandre Lisione24852d2014-02-04 13:13:02 -05001894 zidRec.resetSasVerified();
Alexandre Lision51140e12013-12-02 10:54:09 -05001895 }
1896 else { // No valid RS record in cache
1897 sendInfo(Warning, WarningNoRSMatch);
1898 }
1899 }
1900 else { // at least one RS matches
1901 sendInfo(Info, InfoRSMatchFound);
1902 }
1903
1904 /*
1905 * ready to generate s0 here.
1906 * The formular to compute S0 (Refer to ZRTP specification 5.4.4):
1907 *
1908 s0 = hash( counter | DHResult | "ZRTP-HMAC-KDF" | ZIDi | ZIDr | \
1909 total_hash | len(s1) | s1 | len(s2) | s2 | len(s3) | s3)
1910 *
1911 * Note: in this function we are Responder, thus ZIDi is the peer's zid
1912 * (peerZid), ZIDr is our zid.
1913 */
1914
1915 /*
1916 * These arrays hold the pointers and lengths of the data that must be
1917 * hashed to create S0. According to the formula the max number of
1918 * elements to hash is 12, add one for the terminating "NULL"
1919 */
1920 unsigned char* data[13];
1921 unsigned int length[13];
1922 uint32_t pos = 0; // index into the array
1923
1924
1925 // we need a number of length data items, so define them here
1926 uint32_t counter, sLen[3];
1927
1928 //Very first element is a fixed counter, big endian
1929 counter = 1;
Alexandre Lisione24852d2014-02-04 13:13:02 -05001930 counter = htonl(counter);
Alexandre Lision51140e12013-12-02 10:54:09 -05001931 data[pos] = (unsigned char*)&counter;
1932 length[pos++] = sizeof(uint32_t);
1933
1934 // Next is the DH result itself
1935 data[pos] = DHss;
1936 length[pos++] = dhContext->getDhSize();
1937
1938 // Next the fixed string "ZRTP-HMAC-KDF"
1939 data[pos] = (unsigned char*)KDFString;
1940 length[pos++] = strlen(KDFString);
1941
1942 // Next is Initiator's id (ZIDi), in this case as Responder
1943 // it is peerZid
1944 data[pos] = peerZid;
1945 length[pos++] = ZID_SIZE;
1946
1947 // Next is Responder's id (ZIDr), in this case our own zid
Alexandre Lisione24852d2014-02-04 13:13:02 -05001948 data[pos] = zid;
Alexandre Lision51140e12013-12-02 10:54:09 -05001949 length[pos++] = ZID_SIZE;
1950
1951 // Next ist total hash (messageHash) itself
1952 data[pos] = messageHash;
1953 length[pos++] = hashLength;
1954
1955 /*
1956 * For each matching shared secret hash the length of
1957 * the shared secret as 32 bit big-endian number followd by the
1958 * shared secret itself. The length of a shared seceret is
1959 * currently fixed to SHA256_DIGEST_LENGTH. If a shared
1960 * secret is not used _only_ its length is hased as zero
1961 * length. NOTE: if implementing auxSecret and/or pbxSecret -> check
1962 * this length stuff again.
1963 */
1964 int secretHashLen = RS_LENGTH;
Alexandre Lisione24852d2014-02-04 13:13:02 -05001965 secretHashLen = htonl(secretHashLen); // prepare 32 bit big-endian number
Alexandre Lision51140e12013-12-02 10:54:09 -05001966
1967 for (int32_t i = 0; i < 3; i++) {
1968 if (setD[i] != NULL) { // a matching secret, set length, then secret
1969 sLen[i] = secretHashLen;
1970 data[pos] = (unsigned char*)&sLen[i];
1971 length[pos++] = sizeof(uint32_t);
1972 data[pos] = (unsigned char*)setD[i];
Alexandre Lisione24852d2014-02-04 13:13:02 -05001973 length[pos++] = RS_LENGTH;
Alexandre Lision51140e12013-12-02 10:54:09 -05001974 }
1975 else { // no machting secret, set length 0, skip secret
1976 sLen[i] = 0;
1977 data[pos] = (unsigned char*)&sLen[i];
1978 length[pos++] = sizeof(uint32_t);
1979 }
1980 }
1981
1982 data[pos] = NULL;
1983 hashListFunction(data, length, s0);
1984// hexdump("S0 R", s0, hashLength);
1985
1986 memset(DHss, 0, dhContext->getDhSize());
1987 delete[] DHss;
1988 DHss = NULL;
1989
1990 computeSRTPKeys();
1991 memset(s0, 0, MAX_DIGEST_LENGTH);
1992}
1993
1994
1995void ZRtp::KDF(uint8_t* key, uint32_t keyLength, uint8_t* label, int32_t labelLength,
1996 uint8_t* context, int32_t contextLength, int32_t L, uint8_t* output) {
1997
1998 unsigned char* data[6];
1999 uint32_t length[6];
2000 uint32_t pos = 0; // index into the array
2001 uint32_t maclen = 0;
2002
2003 // Very first element is a fixed counter, big endian
2004 uint32_t counter = 1;
Alexandre Lisione24852d2014-02-04 13:13:02 -05002005 counter = htonl(counter);
Alexandre Lision51140e12013-12-02 10:54:09 -05002006 data[pos] = (unsigned char*)&counter;
2007 length[pos++] = sizeof(uint32_t);
2008
2009 // Next element is the label, null terminated, labelLength includes null byte.
2010 data[pos] = label;
2011 length[pos++] = labelLength;
2012
2013 // Next is the KDF context
2014 data[pos] = context;
2015 length[pos++] = contextLength;
2016
2017 // last element is HMAC length in bits, big endian
Alexandre Lisione24852d2014-02-04 13:13:02 -05002018 uint32_t len = htonl(L);
Alexandre Lision51140e12013-12-02 10:54:09 -05002019 data[pos] = (unsigned char*)&len;
2020 length[pos++] = sizeof(uint32_t);
2021
2022 data[pos] = NULL;
2023
2024 // Use negotiated hash.
2025 hmacListFunction(key, keyLength, data, length, output, &maclen);
2026}
2027
2028// Compute the Multi Stream mode s0
2029void ZRtp::generateKeysMultiStream() {
2030
2031 // allocate the maximum size, compute real size to use
Alexandre Lisione24852d2014-02-04 13:13:02 -05002032 uint8_t KDFcontext[sizeof(peerZid)+sizeof(zid)+sizeof(messageHash)];
2033 int32_t kdfSize = sizeof(peerZid)+sizeof(zid)+hashLength;
Alexandre Lision51140e12013-12-02 10:54:09 -05002034
2035 if (myRole == Responder) {
2036 memcpy(KDFcontext, peerZid, sizeof(peerZid));
Alexandre Lisione24852d2014-02-04 13:13:02 -05002037 memcpy(KDFcontext+sizeof(peerZid), zid, sizeof(zid));
Alexandre Lision51140e12013-12-02 10:54:09 -05002038 }
2039 else {
Alexandre Lisione24852d2014-02-04 13:13:02 -05002040 memcpy(KDFcontext, zid, sizeof(zid));
2041 memcpy(KDFcontext+sizeof(zid), peerZid, sizeof(peerZid));
Alexandre Lision51140e12013-12-02 10:54:09 -05002042 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05002043 memcpy(KDFcontext+sizeof(zid)+sizeof(peerZid), messageHash, hashLength);
Alexandre Lision51140e12013-12-02 10:54:09 -05002044
2045 KDF(zrtpSession, hashLength, (unsigned char*)zrtpMsk, strlen(zrtpMsk)+1, KDFcontext, kdfSize, hashLength*8, s0);
2046
2047 memset(KDFcontext, 0, sizeof(KDFcontext));
2048
2049 computeSRTPKeys();
2050}
2051
2052void ZRtp::computePBXSecret() {
2053 // Construct the KDF context as per ZRTP specification chap 7.3.1:
2054 // ZIDi || ZIDr
Alexandre Lisione24852d2014-02-04 13:13:02 -05002055 uint8_t KDFcontext[sizeof(peerZid)+sizeof(zid)];
2056 int32_t kdfSize = sizeof(peerZid)+sizeof(zid);
Alexandre Lision51140e12013-12-02 10:54:09 -05002057
2058 if (myRole == Responder) {
2059 memcpy(KDFcontext, peerZid, sizeof(peerZid));
Alexandre Lisione24852d2014-02-04 13:13:02 -05002060 memcpy(KDFcontext+sizeof(peerZid), zid, sizeof(zid));
Alexandre Lision51140e12013-12-02 10:54:09 -05002061 }
2062 else {
Alexandre Lisione24852d2014-02-04 13:13:02 -05002063 memcpy(KDFcontext, zid, sizeof(zid));
2064 memcpy(KDFcontext+sizeof(zid), peerZid, sizeof(peerZid));
Alexandre Lision51140e12013-12-02 10:54:09 -05002065 }
2066
2067 KDF(zrtpSession, hashLength, (unsigned char*)zrtpTrustedMitm, strlen(zrtpTrustedMitm)+1, KDFcontext,
2068 kdfSize, SHA256_DIGEST_LENGTH * 8, pbxSecretTmpBuffer);
2069
2070 pbxSecretTmp = pbxSecretTmpBuffer; // set pointer to buffer, signal PBX secret was computed
2071}
2072
2073
2074void ZRtp::computeSRTPKeys() {
2075
2076 // allocate the maximum size, compute real size to use
Alexandre Lisione24852d2014-02-04 13:13:02 -05002077 uint8_t KDFcontext[sizeof(peerZid)+sizeof(zid)+sizeof(messageHash)];
2078 int32_t kdfSize = sizeof(peerZid)+sizeof(zid)+hashLength;
Alexandre Lision51140e12013-12-02 10:54:09 -05002079
2080 int32_t keyLen = cipher->getKeylen() * 8;
2081
2082 if (myRole == Responder) {
2083 memcpy(KDFcontext, peerZid, sizeof(peerZid));
Alexandre Lisione24852d2014-02-04 13:13:02 -05002084 memcpy(KDFcontext+sizeof(peerZid), zid, sizeof(zid));
Alexandre Lision51140e12013-12-02 10:54:09 -05002085 }
2086 else {
Alexandre Lisione24852d2014-02-04 13:13:02 -05002087 memcpy(KDFcontext, zid, sizeof(zid));
2088 memcpy(KDFcontext+sizeof(zid), peerZid, sizeof(peerZid));
Alexandre Lision51140e12013-12-02 10:54:09 -05002089 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05002090 memcpy(KDFcontext+sizeof(zid)+sizeof(peerZid), messageHash, hashLength);
Alexandre Lision51140e12013-12-02 10:54:09 -05002091
2092 // Inititiator key and salt
2093 KDF(s0, hashLength, (unsigned char*)iniMasterKey, strlen(iniMasterKey)+1, KDFcontext, kdfSize, keyLen, srtpKeyI);
2094 KDF(s0, hashLength, (unsigned char*)iniMasterSalt, strlen(iniMasterSalt)+1, KDFcontext, kdfSize, 112, srtpSaltI);
2095
2096 // Responder key and salt
2097 KDF(s0, hashLength, (unsigned char*)respMasterKey, strlen(respMasterKey)+1, KDFcontext, kdfSize, keyLen, srtpKeyR);
2098 KDF(s0, hashLength, (unsigned char*)respMasterSalt, strlen(respMasterSalt)+1, KDFcontext, kdfSize, 112, srtpSaltR);
2099
2100 // The HMAC keys for GoClear
2101 KDF(s0, hashLength, (unsigned char*)iniHmacKey, strlen(iniHmacKey)+1, KDFcontext, kdfSize, hashLength*8, hmacKeyI);
Alexandre Lisione24852d2014-02-04 13:13:02 -05002102
Alexandre Lision51140e12013-12-02 10:54:09 -05002103 KDF(s0, hashLength, (unsigned char*)respHmacKey, strlen(respHmacKey)+1, KDFcontext, kdfSize, hashLength*8, hmacKeyR);
2104
2105 // The keys for Confirm messages
2106 KDF(s0, hashLength, (unsigned char*)iniZrtpKey, strlen(iniZrtpKey)+1, KDFcontext, kdfSize, keyLen, zrtpKeyI);
2107 KDF(s0, hashLength, (unsigned char*)respZrtpKey, strlen(respZrtpKey)+1, KDFcontext, kdfSize, keyLen, zrtpKeyR);
2108
2109 if (!multiStream) {
2110 // Compute the new Retained Secret
2111 KDF(s0, hashLength, (unsigned char*)retainedSec, strlen(retainedSec)+1, KDFcontext, kdfSize, SHA256_DIGEST_LENGTH*8, newRs1);
2112
2113 // Compute the ZRTP Session Key
2114 KDF(s0, hashLength, (unsigned char*)zrtpSessionKey, strlen(zrtpSessionKey)+1, KDFcontext, kdfSize, hashLength*8, zrtpSession);
2115
Alexandre Lisione24852d2014-02-04 13:13:02 -05002116 // perform SAS generation according to chapter 5.5 and 8.
Alexandre Lision51140e12013-12-02 10:54:09 -05002117 // we don't need a speciai sasValue filed. sasValue are the first
2118 // (leftmost) 32 bits (4 bytes) of sasHash
2119 uint8_t sasBytes[4];
2120 KDF(s0, hashLength, (unsigned char*)sasString, strlen(sasString)+1, KDFcontext, kdfSize, SHA256_DIGEST_LENGTH*8, sasHash);
2121
2122 // according to chapter 8 only the leftmost 20 bits of sasValue (aka
2123 // sasHash) are used to create the character SAS string of type SAS
2124 // base 32 (5 bits per character)
2125 sasBytes[0] = sasHash[0];
2126 sasBytes[1] = sasHash[1];
2127 sasBytes[2] = sasHash[2] & 0xf0;
2128 sasBytes[3] = 0;
Alexandre Lisione24852d2014-02-04 13:13:02 -05002129 SAS = Base32(sasBytes, 20).getEncoded();
Alexandre Lision51140e12013-12-02 10:54:09 -05002130 if (signSasSeen)
2131 callback->signSAS(sasHash);
2132 }
2133 memset(KDFcontext, 0, sizeof(KDFcontext));
2134}
2135
2136bool ZRtp::srtpSecretsReady(EnableSecurity part) {
2137
2138 SrtpSecret_t sec;
2139
2140 sec.symEncAlgorithm = cipher->getAlgoId();
2141
2142 sec.keyInitiator = srtpKeyI;
2143 sec.initKeyLen = cipher->getKeylen() * 8;
2144 sec.saltInitiator = srtpSaltI;
2145 sec.initSaltLen = 112;
2146
2147 sec.keyResponder = srtpKeyR;
2148 sec.respKeyLen = cipher->getKeylen() * 8;
2149 sec.saltResponder = srtpSaltR;
2150 sec.respSaltLen = 112;
2151
2152 sec.authAlgorithm = authLength->getAlgoId();
2153 sec.srtpAuthTagLen = authLength->getKeylen();
2154
2155 sec.sas = SAS;
2156 sec.role = myRole;
2157
Alexandre Lisione24852d2014-02-04 13:13:02 -05002158 return callback->srtpSecretsReady(&sec, part);
Alexandre Lision51140e12013-12-02 10:54:09 -05002159}
2160
2161
2162void ZRtp::setNegotiatedHash(AlgorithmEnum* hash) {
2163 switch (zrtpHashes.getOrdinal(*hash)) {
2164 case 0:
2165 hashLength = SHA256_DIGEST_LENGTH;
2166 hashFunction = sha256;
2167 hashListFunction = sha256;
2168
2169 hmacFunction = hmac_sha256;
2170 hmacListFunction = hmac_sha256;
2171
2172 createHashCtx = createSha256Context;
2173 closeHashCtx = closeSha256Context;
2174 hashCtxFunction = sha256Ctx;
2175 hashCtxListFunction = sha256Ctx;
2176 break;
2177
2178 case 1:
2179 hashLength = SHA384_DIGEST_LENGTH;
2180 hashFunction = sha384;
2181 hashListFunction = sha384;
2182
2183 hmacFunction = hmac_sha384;
2184 hmacListFunction = hmac_sha384;
2185
2186 createHashCtx = createSha384Context;
2187 closeHashCtx = closeSha384Context;
2188 hashCtxFunction = sha384Ctx;
2189 hashCtxListFunction = sha384Ctx;
2190 break;
2191 }
2192}
2193
2194
2195void ZRtp::srtpSecretsOff(EnableSecurity part) {
2196 callback->srtpSecretsOff(part);
2197}
2198
2199void ZRtp::SASVerified() {
2200 if (paranoidMode)
2201 return;
2202
Alexandre Lisione24852d2014-02-04 13:13:02 -05002203 // Initialize a ZID record to get peer's retained secrets
2204 ZIDRecord zidRec(peerZid);
2205 ZIDFile *zid = ZIDFile::getInstance();
2206
2207 zid->getRecord(&zidRec);
2208 zidRec.setSasVerified();
2209 zid->saveRecord(&zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -05002210}
2211
2212void ZRtp::resetSASVerified() {
Alexandre Lisione24852d2014-02-04 13:13:02 -05002213 // Initialize a ZID record to get peer's retained secrets
2214 ZIDRecord zidRec(peerZid);
2215 ZIDFile *zid = ZIDFile::getInstance();
Alexandre Lision51140e12013-12-02 10:54:09 -05002216
Alexandre Lisione24852d2014-02-04 13:13:02 -05002217 zid->getRecord(&zidRec);
2218 zidRec.resetSasVerified();
2219 zid->saveRecord(&zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -05002220}
2221
2222
2223void ZRtp::sendInfo(GnuZrtpCodes::MessageSeverity severity, int32_t subCode) {
2224
2225 // We've reached secure state: overwrite the SRTP master key and master salt.
2226 if (severity == Info && subCode == InfoSecureStateOn) {
2227 memset(srtpKeyI, 0, cipher->getKeylen());
2228 memset(srtpSaltI, 0, 112/8);
2229 memset(srtpKeyR, 0, cipher->getKeylen());
2230 memset(srtpSaltR, 0, 112/8);
2231 }
2232 callback->sendInfo(severity, subCode);
2233}
2234
2235
2236void ZRtp::zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity severity, int32_t subCode) {
2237 callback->zrtpNegotiationFailed(severity, subCode);
2238}
2239
2240void ZRtp::zrtpNotSuppOther() {
2241 callback->zrtpNotSuppOther();
2242}
2243
2244void ZRtp::synchEnter() {
2245 callback->synchEnter();
2246}
2247
2248void ZRtp::synchLeave() {
2249 callback->synchLeave();
2250}
2251
2252int32_t ZRtp::sendPacketZRTP(ZrtpPacketBase *packet) {
2253 return ((packet == NULL) ? 0 :
2254 callback->sendDataZRTP(packet->getHeaderBase(), (packet->getLength() * 4) + 4));
2255}
2256
2257int32_t ZRtp::activateTimer(int32_t tm) {
2258 return (callback->activateTimer(tm));
2259}
2260
2261int32_t ZRtp::cancelTimer() {
2262 return (callback->cancelTimer());
2263}
2264
2265void ZRtp::setAuxSecret(uint8_t* data, int32_t length) {
2266 if (length > 0) {
2267 auxSecret = new uint8_t[length];
2268 auxSecretLength = length;
2269 memcpy(auxSecret, data, length);
2270 }
2271}
2272
Alexandre Lisione24852d2014-02-04 13:13:02 -05002273void ZRtp::setClientId(std::string id) {
2274 if (id.size() < CLIENT_ID_SIZE) {
2275 unsigned char tmp[CLIENT_ID_SIZE +1] = {' '};
2276 memcpy(tmp, id.c_str(), id.size());
2277 tmp[CLIENT_ID_SIZE] = 0;
2278 zrtpHello.setClientId(tmp);
2279 } else {
2280 zrtpHello.setClientId((unsigned char*)id.c_str());
2281 }
Alexandre Lision51140e12013-12-02 10:54:09 -05002282
Alexandre Lisione24852d2014-02-04 13:13:02 -05002283 int32_t len = zrtpHello.getLength() * ZRTP_WORD_SIZE;
Alexandre Lision51140e12013-12-02 10:54:09 -05002284
Alexandre Lisione24852d2014-02-04 13:13:02 -05002285 // Hello packet is ready now, compute its HMAC
Alexandre Lision51140e12013-12-02 10:54:09 -05002286 // (excluding the HMAC field (2*ZTP_WORD_SIZE)) and store in Hello
2287 // use the implicit hash function
2288 uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];
2289 uint32_t macLen;
Alexandre Lisione24852d2014-02-04 13:13:02 -05002290 hmacFunctionImpl(H2, HASH_IMAGE_SIZE, (uint8_t*)zrtpHello.getHeaderBase(), len-(2*ZRTP_WORD_SIZE), hmac, &macLen);
2291 zrtpHello.setHMAC(hmac);
Alexandre Lision51140e12013-12-02 10:54:09 -05002292
2293 // calculate hash over the final Hello packet, refer to chap 9.1 how to
2294 // use this hash in SIP/SDP.
Alexandre Lisione24852d2014-02-04 13:13:02 -05002295 hashFunctionImpl((uint8_t*)zrtpHello.getHeaderBase(), len, helloHash);
Alexandre Lision51140e12013-12-02 10:54:09 -05002296}
2297
2298void ZRtp::storeMsgTemp(ZrtpPacketBase* pkt) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05002299 int32_t length = pkt->getLength() * ZRTP_WORD_SIZE;
Alexandre Lision51140e12013-12-02 10:54:09 -05002300 memset(tempMsgBuffer, 0, sizeof(tempMsgBuffer));
2301 memcpy(tempMsgBuffer, (uint8_t*)pkt->getHeaderBase(), length);
2302 lengthOfMsgData = length;
2303}
2304
2305bool ZRtp::checkMsgHmac(uint8_t* key) {
2306 uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];
2307 uint32_t macLen;
2308 int32_t len = lengthOfMsgData-(HMAC_SIZE); // compute HMAC, but exlude the stored HMAC :-)
2309
2310 // Use the implicit hash function
2311 hmacFunctionImpl(key, HASH_IMAGE_SIZE, tempMsgBuffer, len, hmac, &macLen);
2312 return (memcmp(hmac, tempMsgBuffer+len, (HMAC_SIZE)) == 0 ? true : false);
2313}
2314
Alexandre Lisione24852d2014-02-04 13:13:02 -05002315std::string ZRtp::getHelloHash() {
Alexandre Lision51140e12013-12-02 10:54:09 -05002316 std::ostringstream stm;
2317
Alexandre Lisione24852d2014-02-04 13:13:02 -05002318 uint8_t* hp = helloHash;
Alexandre Lision51140e12013-12-02 10:54:09 -05002319
Alexandre Lisione24852d2014-02-04 13:13:02 -05002320 stm << zrtpVersion;
Alexandre Lision51140e12013-12-02 10:54:09 -05002321 stm << " ";
2322 stm.fill('0');
2323 stm << hex;
2324 for (int i = 0; i < hashLengthImpl; i++) {
2325 stm.width(2);
2326 stm << static_cast<uint32_t>(*hp++);
2327 }
2328 return stm.str();
2329}
2330
2331std::string ZRtp::getPeerHelloHash() {
2332 std::ostringstream stm;
2333
2334 if (peerHelloVersion[0] == 0)
2335 return std::string();
2336
2337 uint8_t* hp = peerHelloHash;
2338
2339 stm << peerHelloVersion;
2340 stm << " ";
2341 stm.fill('0');
2342 stm << hex;
2343 for (int i = 0; i < hashLengthImpl; i++) {
2344 stm.width(2);
2345 stm << static_cast<uint32_t>(*hp++);
2346 }
2347 return stm.str();
2348}
2349
2350std::string ZRtp::getMultiStrParams() {
2351
2352 // the string will hold binary data - it's opaque to the application
2353 std::string str("");
2354 char tmp[MAX_DIGEST_LENGTH + 1 + 1 + 1]; // hash length + cipher + authLength + hash
2355
2356 if (inState(SecureState) && !multiStream) {
2357 // construct array that holds zrtpSession, cipher type, auth-length, and hash type
2358 tmp[0] = zrtpHashes.getOrdinal(*hash);
2359 tmp[1] = zrtpAuthLengths.getOrdinal(*authLength);
2360 tmp[2] = zrtpSymCiphers.getOrdinal(*cipher);
2361 memcpy(tmp+3, zrtpSession, hashLength);
2362 str.assign(tmp, hashLength + 1 + 1 + 1); // set chars (bytes) to the string
2363 }
2364 return str;
2365}
2366
2367void ZRtp::setMultiStrParams(std::string parameters) {
2368
2369 char tmp[MAX_DIGEST_LENGTH + 1 + 1 + 1]; // max. hash length + cipher + authLength + hash
2370
2371 // First get negotiated hash from parameters, set algorithms and length
2372 int i = parameters.at(0) & 0xff;
2373 hash = &zrtpHashes.getByOrdinal(i);
2374 setNegotiatedHash(hash); // sets hashlength
2375
2376 // use string.copy(buffer, num, start=0) to retrieve chars (bytes) from the string
2377 parameters.copy(tmp, hashLength + 1 + 1 + 1, 0);
2378
2379 i = tmp[1] & 0xff;
2380 authLength = &zrtpAuthLengths.getByOrdinal(i);
2381 i = tmp[2] & 0xff;
2382 cipher = &zrtpSymCiphers.getByOrdinal(i);
2383 memcpy(zrtpSession, tmp+3, hashLength);
2384
2385 // after setting zrtpSession, cipher, and auth-length set multi-stream to true
2386 multiStream = true;
2387 stateEngine->setMultiStream(true);
2388}
2389
2390bool ZRtp::isMultiStream() {
2391 return multiStream;
2392}
2393
2394bool ZRtp::isMultiStreamAvailable() {
2395 return multiStreamAvailable;
2396}
2397
2398void ZRtp::acceptEnrollment(bool accepted) {
2399 if (!accepted) {
2400 callback->zrtpInformEnrollment(EnrollmentCanceled);
2401 return;
2402 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05002403 // Get peer's zid record to store the pbx (MitM) secret
2404 // Initialize a ZID record to get peer's retained secrets
2405 ZIDRecord zidRec(peerZid);
2406 ZIDFile* zid = ZIDFile::getInstance();
2407 zid->getRecord(&zidRec);
2408
Alexandre Lision51140e12013-12-02 10:54:09 -05002409 if (pbxSecretTmp != NULL) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05002410 zidRec.setMiTMData(pbxSecretTmp);
Alexandre Lision51140e12013-12-02 10:54:09 -05002411 callback->zrtpInformEnrollment(EnrollmentOk);
2412 }
2413 else {
2414 callback->zrtpInformEnrollment(EnrollmentFailed);
Alexandre Lisione24852d2014-02-04 13:13:02 -05002415 return;
Alexandre Lision51140e12013-12-02 10:54:09 -05002416 }
Alexandre Lisione24852d2014-02-04 13:13:02 -05002417 zid->saveRecord(&zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -05002418 return;
2419}
2420
2421bool ZRtp::setSignatureData(uint8_t* data, int32_t length) {
2422 if ((length % 4) != 0)
2423 return false;
2424
2425 ZrtpPacketConfirm* cfrm = (myRole == Responder) ? &zrtpConfirm1 : &zrtpConfirm2;
2426 cfrm->setSignatureLength(length / 4);
2427 return cfrm->setSignatureData(data, length);
2428}
2429
2430const uint8_t* ZRtp::getSignatureData() {
2431 return signatureData;
2432}
2433
2434int32_t ZRtp::getSignatureLength() {
2435 return signatureLength * ZRTP_WORD_SIZE;
2436}
2437
2438void ZRtp::conf2AckSecure() {
2439 Event_t ev;
2440
2441 ev.type = ZrtpPacket;
Alexandre Lisione24852d2014-02-04 13:13:02 -05002442 ev.packet = (uint8_t*)&zrtpConf2Ack;
Alexandre Lision51140e12013-12-02 10:54:09 -05002443
2444 if (stateEngine != NULL) {
2445 stateEngine->processEvent(&ev);
2446 }
2447}
2448
2449int32_t ZRtp::compareCommit(ZrtpPacketCommit *commit) {
Alexandre Lisione24852d2014-02-04 13:13:02 -05002450 // TODO: enhance to compare according to rules defined in chapter 4.2
Alexandre Lision51140e12013-12-02 10:54:09 -05002451 int32_t len = 0;
2452 len = !multiStream ? HVI_SIZE : (4 * ZRTP_WORD_SIZE);
2453 return (memcmp(hvi, commit->getHvi(), len));
2454}
2455
2456bool ZRtp::isEnrollmentMode() {
2457 return enrollmentMode;
2458}
2459
2460void ZRtp::setEnrollmentMode(bool enrollmentMode) {
2461 this->enrollmentMode = enrollmentMode;
2462}
2463
2464bool ZRtp::isPeerEnrolled() {
2465 return peerIsEnrolled;
2466}
2467
2468bool ZRtp::sendSASRelayPacket(uint8_t* sh, std::string render) {
2469
2470 uint8_t confMac[MAX_DIGEST_LENGTH];
2471 uint32_t macLen;
2472 uint8_t* hkey, *ekey;
2473
2474 // If we are responder then the PBX used it's Initiator keys
2475 if (myRole == Responder) {
2476 hkey = hmacKeyR;
2477 ekey = zrtpKeyR;
2478 // TODO: check signature length in zrtpConfirm1 and if not zero copy Signature data
2479 }
2480 else {
2481 hkey = hmacKeyI;
2482 ekey = zrtpKeyI;
2483 // TODO: check signature length in zrtpConfirm2 and if not zero copy Signature data
2484 }
2485 // Prepare IV data that we will use during confirm packet encryption.
2486 randomZRTP(randomIV, sizeof(randomIV));
2487 zrtpSasRelay.setIv(randomIV);
2488 zrtpSasRelay.setTrustedSas(sh);
Alexandre Lisione24852d2014-02-04 13:13:02 -05002489 zrtpSasRelay.setSas((uint8_t*)render.c_str());
Alexandre Lision51140e12013-12-02 10:54:09 -05002490
Alexandre Lisione24852d2014-02-04 13:13:02 -05002491 // Encrypt and HMAC with Initiator's key - we are Initiator here
Alexandre Lision51140e12013-12-02 10:54:09 -05002492 int16_t hmlen = (zrtpSasRelay.getLength() - 9) * ZRTP_WORD_SIZE;
2493 cipher->getEncrypt()(ekey, cipher->getKeylen(), randomIV, (uint8_t*)zrtpSasRelay.getFiller(), hmlen);
2494
2495 // Use negotiated HMAC (hash)
2496 hmacFunction(hkey, hashLength, (unsigned char*)zrtpSasRelay.getFiller(), hmlen, confMac, &macLen);
2497
2498 zrtpSasRelay.setHmac(confMac);
2499
2500 stateEngine->sendSASRelay(&zrtpSasRelay);
2501 return true;
2502}
2503
2504std::string ZRtp::getSasType() {
2505 std::string sasT(sasType->getName());
2506 return sasT;
2507}
2508
2509uint8_t* ZRtp::getSasHash() {
2510 return sasHash;
2511}
2512
2513int32_t ZRtp::getPeerZid(uint8_t* data) {
2514 memcpy(data, peerZid, IDENTIFIER_LEN);
2515 return IDENTIFIER_LEN;
2516}
2517
Alexandre Lision51140e12013-12-02 10:54:09 -05002518/** EMACS **
2519 * Local variables:
2520 * mode: c++
2521 * c-default-style: ellemtel
2522 * c-basic-offset: 4
2523 * End:
2524 */
2525