blob: 9fb8e0aa97c07cde06d0f1148a108cb7e4daa5cd [file] [log] [blame]
Alexandre Lision51140e12013-12-02 10:54:09 -05001/*
Alexandre Lisionddd731e2014-01-31 11:50:08 -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 Lisionddd731e2014-01-31 11:50:08 -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 Lision7fd5d3d2013-12-04 13:06:40 -050018/*
Alexandre Lision51140e12013-12-02 10:54:09 -050019 * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
20 */
21#include <sstream>
22
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050023#include <crypto/zrtpDH.h>
24#include <crypto/hmac256.h>
25#include <crypto/sha256.h>
26#include <crypto/hmac384.h>
27#include <crypto/sha384.h>
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050028#include <crypto/aesCFB.h>
29#include <crypto/twoCFB.h>
Alexandre Lision51140e12013-12-02 10:54:09 -050030
31#include <libzrtpcpp/ZRtp.h>
32#include <libzrtpcpp/ZrtpStateClass.h>
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050033#include <libzrtpcpp/ZIDCache.h>
Alexandre Lision51140e12013-12-02 10:54:09 -050034#include <libzrtpcpp/Base32.h>
35
36using namespace GnuZrtpCodes;
37
38/* disabled...but used in testing and debugging, probably should have a
39 controlling #define...
40 *
41static void hexdump(const char* title, const unsigned char *s, int l) {
42 int n=0;
43
44 if (s == NULL) return;
45
46 fprintf(stderr, "%s",title);
47 for( ; n < l ; ++n)
48 {
49 if((n%16) == 0)
50 fprintf(stderr, "\n%04x",n);
51 fprintf(stderr, " %02x",s[n]);
52 }
53 fprintf(stderr, "\n");
54}
Alexandre Lisionddd731e2014-01-31 11:50:08 -050055 */
Alexandre Lision51140e12013-12-02 10:54:09 -050056
57/*
58 * This method simplifies detection of libzrtpcpp inside Automake, configure
59 * and friends
60 */
61#ifdef __cplusplus
62extern "C" {
63#endif
64 int ZrtpAvailable()
65 {
66 return 1;
67 }
68#ifdef __cplusplus
69}
70#endif
71
72ZRtp::ZRtp(uint8_t *myZid, ZrtpCallback *cb, std::string id, ZrtpConfigure* config, bool mitmm, bool sasSignSupport):
73 callback(cb), dhContext(NULL), DHss(NULL), auxSecret(NULL), auxSecretLength(0), rs1Valid(false),
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050074 rs2Valid(false), msgShaContext(NULL), hash(NULL), cipher(NULL), pubKey(NULL), sasType(NULL), authLength(NULL),
75 multiStream(false), multiStreamAvailable(false), peerIsEnrolled(false), mitmSeen(false), pbxSecretTmp(NULL),
Alexandre Lisionddd731e2014-01-31 11:50:08 -050076 enrollmentMode(false), configureAlgos(*config), zidRec(NULL) {
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 Lisionddd731e2014-01-31 11:50:08 -050098 zrtpHello.configureHello(&configureAlgos);
99 zrtpHello.setH3(H3); // set H3 in Hello, included in helloHash
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500100 peerHelloVersion[0] = 0;
Alexandre Lision51140e12013-12-02 10:54:09 -0500101
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500102 memcpy(ownZid, myZid, ZID_SIZE);
103 zrtpHello.setZid(ownZid);
104
105 if (mitmm) // this session acts for a trusted MitM (PBX)
106 zrtpHello.setMitmMode();
107
108 if (sasSignSupport) // the application supports SAS signing
109 zrtpHello.setSasSign();
110
111 setClientId(id); // set id, compute HMAC and final helloHash
112
Alexandre Lision51140e12013-12-02 10:54:09 -0500113 stateEngine = new ZrtpStateClass(this);
114}
115
116ZRtp::~ZRtp() {
117 stopZrtp();
118 if (DHss != NULL) {
119 delete DHss;
120 DHss = NULL;
121 }
122 if (stateEngine != NULL) {
123 delete stateEngine;
124 stateEngine = NULL;
125 }
126 if (dhContext != NULL) {
127 delete dhContext;
128 dhContext = NULL;
129 }
130 if (msgShaContext != NULL) {
131 closeHashCtx(msgShaContext, NULL);
132 msgShaContext = NULL;
133 }
134 if (auxSecret != NULL) {
135 delete auxSecret;
136 auxSecret = NULL;
137 auxSecretLength = 0;
138 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500139 if (zidRec != NULL) {
140 delete zidRec;
141 zidRec = NULL;
142 }
Alexandre Lision51140e12013-12-02 10:54:09 -0500143 memset(hmacKeyI, 0, MAX_DIGEST_LENGTH);
144 memset(hmacKeyR, 0, MAX_DIGEST_LENGTH);
145
146 memset(zrtpKeyI, 0, MAX_DIGEST_LENGTH);
147 memset(zrtpKeyR, 0, MAX_DIGEST_LENGTH);
148 /*
149 * Clear the Initiator's srtp key and salt
150 */
151 memset(srtpKeyI, 0, MAX_DIGEST_LENGTH);
152 memset(srtpSaltI, 0, MAX_DIGEST_LENGTH);
153 /*
154 * Clear he Responder's srtp key and salt
155 */
156 memset(srtpKeyR, 0, MAX_DIGEST_LENGTH);
157 memset(srtpSaltR, 0, MAX_DIGEST_LENGTH);
158
159 memset(zrtpSession, 0, MAX_DIGEST_LENGTH);
160}
161
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500162void ZRtp::processZrtpMessage(uint8_t *message, uint32_t pSSRC, size_t length) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500163 Event_t ev;
164
165 peerSSRC = pSSRC;
166 ev.type = ZrtpPacket;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500167 ev.length = length;
Alexandre Lision51140e12013-12-02 10:54:09 -0500168 ev.packet = message;
169
170 if (stateEngine != NULL) {
171 stateEngine->processEvent(&ev);
172 }
173}
174
175void ZRtp::processTimeout() {
176 Event_t ev;
177
178 ev.type = Timer;
179 if (stateEngine != NULL) {
180 stateEngine->processEvent(&ev);
181 }
182}
183
184#ifdef oldgoclear
185bool ZRtp::handleGoClear(uint8_t *message)
186{
187 char *msg, first, last;
188
189 msg = (char *)message + 4;
190 first = tolower(*msg);
191 last = tolower(*(msg+6));
192
193 if (first == 'g' && last == 'r') {
194 Event_t ev;
195
196 ev.type = ZrtpGoClear;
197 ev.packet = message;
198 if (stateEngine != NULL) {
199 stateEngine->processEvent(&ev);
200 }
201 return true;
202 }
203 else {
204 return false;
205 }
206}
207#endif
208
209void ZRtp::startZrtpEngine() {
210 Event_t ev;
211
212 if (stateEngine != NULL && stateEngine->inState(Initial)) {
213 ev.type = ZrtpInitial;
214 stateEngine->processEvent(&ev);
215 }
216}
217
218void ZRtp::stopZrtp() {
219 Event_t ev;
220
221 if (stateEngine != NULL) {
222 ev.type = ZrtpClose;
223 stateEngine->processEvent(&ev);
224 }
225}
226
227bool ZRtp::inState(int32_t state)
228{
229 if (stateEngine != NULL) {
230 return stateEngine->inState(state);
231 }
232 else {
233 return false;
234 }
235}
236
237ZrtpPacketHello* ZRtp::prepareHello() {
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500238 return &zrtpHello;
Alexandre Lision51140e12013-12-02 10:54:09 -0500239}
240
241ZrtpPacketHelloAck* ZRtp::prepareHelloAck() {
242 return &zrtpHelloAck;
243}
244
245/*
246 * At this point we will assume the role of Initiator. This role may change
247 * in case we have a commit-clash. Refer to chapter 5.2 in the spec how
248 * to break this tie.
249 */
250ZrtpPacketCommit* ZRtp::prepareCommit(ZrtpPacketHello *hello, uint32_t* errMsg) {
251
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500252 // Save data before detailed checks - may aid in analysing problems
253 peerClientId.assign((char*)hello->getClientId(), ZRTP_WORD_SIZE * 4);
254 memcpy(peerHelloVersion, hello->getVersion(), ZRTP_WORD_SIZE);
255 peerHelloVersion[ZRTP_WORD_SIZE] = 0;
256
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500257 if (memcmp(hello->getVersion(), zrtpVersion, ZRTP_WORD_SIZE-1) != 0) {
258 *errMsg = UnsuppZRTPVersion;
259 return NULL;
260 }
261
Alexandre Lision51140e12013-12-02 10:54:09 -0500262 // Save our peer's (presumably the Responder) ZRTP id
263 memcpy(peerZid, hello->getZid(), ZID_SIZE);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500264 if (memcmp(peerZid, ownZid, ZID_SIZE) == 0) { // peers have same ZID????
Alexandre Lision51140e12013-12-02 10:54:09 -0500265 *errMsg = EqualZIDHello;
266 return NULL;
267 }
268 memcpy(peerH3, hello->getH3(), HASH_IMAGE_SIZE);
269
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500270 int32_t helloLen = hello->getLength() * ZRTP_WORD_SIZE;
271
272 // calculate hash over the received Hello packet - is peer's hello hash.
273 // Use implicit hash algorithm
274 hashFunctionImpl((unsigned char*)hello->getHeaderBase(), helloLen, peerHelloHash);
275
276 sendInfo(Info, InfoHelloReceived);
277
Alexandre Lision51140e12013-12-02 10:54:09 -0500278 /*
279 * The Following section extracts the algorithm from the peer's Hello
280 * packet. Always the preferend offered algorithms are
281 * used. If the received Hello does not contain algo specifiers
282 * or offers only unsupported optional algos then replace
283 * these with mandatory algos and put them into the Commit packet.
284 * Refer to the findBest*() functions.
285 * If this is a MultiStream ZRTP object then do not get the cipher,
286 * authentication from hello packet but use the pre-initialized values
287 * as proposed by the standard. If we switch to responder mode the
288 * commit packet may contain other algos - see function
289 * prepareConfirm2MultiStream(...).
290 */
291 sasType = findBestSASType(hello);
292
293 if (!multiStream) {
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500294 pubKey = findBestPubkey(hello); // Check for public key algorithm first, sets 'hash' as well
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500295 if (hash == NULL) {
296 *errMsg = UnsuppHashType;
297 return NULL;
298 }
299 if (cipher == NULL) // public key selection may have set the cipher already
300 cipher = findBestCipher(hello, pubKey);
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500301 authLength = findBestAuthLen(hello);
Alexandre Lision51140e12013-12-02 10:54:09 -0500302 multiStreamAvailable = checkMultiStream(hello);
303 }
304 else {
305 if (checkMultiStream(hello)) {
306 return prepareCommitMultiStream(hello);
307 }
308 else {
309 // we are in multi-stream but peer does not offer multi-stream
310 // return error code to other party - unsupported PK, must be Mult
311 *errMsg = UnsuppPKExchange;
312 return NULL;
313 }
314 }
315 setNegotiatedHash(hash);
316
317 // Modify here when introducing new DH key agreement, for example
318 // elliptic curves.
319 dhContext = new ZrtpDH(pubKey->getName());
320 dhContext->generatePublicKey();
321
322 dhContext->getPubKeyBytes(pubKeyBytes);
323 sendInfo(Info, InfoCommitDHGenerated);
324
325 // Prepare IV data that we will use during confirm packet encryption.
326 randomZRTP(randomIV, sizeof(randomIV));
327
328 /*
329 * Prepare our DHPart2 packet here. Required to compute HVI. If we stay
330 * in Initiator role then we reuse this packet later in prepareDHPart2().
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500331 * To create this DH packet we have to compute the retained secret ids,
332 * thus get our peer's retained secret data first.
Alexandre Lision51140e12013-12-02 10:54:09 -0500333 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500334 zidRec = getZidCacheInstance()->getRecord(peerZid);
Alexandre Lision51140e12013-12-02 10:54:09 -0500335
336 //Compute the Initator's and Responder's retained secret ids.
337 computeSharedSecretSet(zidRec);
338
339 // Check if a PBX application set the MitM flag.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500340 mitmSeen = hello->isMitmMode();
Alexandre Lision51140e12013-12-02 10:54:09 -0500341
342 signSasSeen = hello->isSasSign();
343 // Construct a DHPart2 message (Initiator's DH message). This packet
344 // is required to compute the HVI (Hash Value Initiator), refer to
345 // chapter 5.4.1.1.
346
347 // Fill the values in the DHPart2 packet
348 zrtpDH2.setPubKeyType(pubKey->getName());
349 zrtpDH2.setMessageType((uint8_t*)DHPart2Msg);
350 zrtpDH2.setRs1Id(rs1IDi);
351 zrtpDH2.setRs2Id(rs2IDi);
352 zrtpDH2.setAuxSecretId(auxSecretIDi);
353 zrtpDH2.setPbxSecretId(pbxSecretIDi);
354 zrtpDH2.setPv(pubKeyBytes);
355 zrtpDH2.setH1(H1);
356
357 int32_t len = zrtpDH2.getLength() * ZRTP_WORD_SIZE;
358
359 // Compute HMAC over DH2, excluding the HMAC field (HMAC_SIZE)
360 // and store in DH2. Key to HMAC is H0, use HASH_IMAGE_SIZE bytes only.
361 // Must use implicit HMAC functions.
362 uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];
363 uint32_t macLen;
364 hmacFunctionImpl(H0, HASH_IMAGE_SIZE, (uint8_t*)zrtpDH2.getHeaderBase(), len-(HMAC_SIZE), hmac, &macLen);
365 zrtpDH2.setHMAC(hmac);
366
367 // Compute the HVI, refer to chapter 5.4.1.1 of the specification
368 computeHvi(&zrtpDH2, hello);
369
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500370 zrtpCommit.setZid(ownZid);
Alexandre Lision51140e12013-12-02 10:54:09 -0500371 zrtpCommit.setHashType((uint8_t*)hash->getName());
372 zrtpCommit.setCipherType((uint8_t*)cipher->getName());
373 zrtpCommit.setAuthLen((uint8_t*)authLength->getName());
374 zrtpCommit.setPubKeyType((uint8_t*)pubKey->getName());
375 zrtpCommit.setSasType((uint8_t*)sasType->getName());
376 zrtpCommit.setHvi(hvi);
377 zrtpCommit.setH2(H2);
378
379 len = zrtpCommit.getLength() * ZRTP_WORD_SIZE;
380
381 // Compute HMAC over Commit, excluding the HMAC field (HMAC_SIZE)
382 // and store in Hello. Key to HMAC is H1, use HASH_IMAGE_SIZE bytes only.
383 // Must use implicit HMAC functions.
384 hmacFunctionImpl(H1, HASH_IMAGE_SIZE, (uint8_t*)zrtpCommit.getHeaderBase(), len-(HMAC_SIZE), hmac, &macLen);
385 zrtpCommit.setHMAC(hmac);
386
387 // hash first messages to produce overall message hash
388 // First the Responder's Hello message, second the Commit (always Initator's).
389 // Must use negotiated hash.
Alexandre Lision51140e12013-12-02 10:54:09 -0500390 msgShaContext = createHashCtx();
391 hashCtxFunction(msgShaContext, (unsigned char*)hello->getHeaderBase(), helloLen);
392 hashCtxFunction(msgShaContext, (unsigned char*)zrtpCommit.getHeaderBase(), len);
393
394 // store Hello data temporarily until we can check HMAC after receiving Commit as
395 // Responder or DHPart1 as Initiator
396 storeMsgTemp(hello);
397
Alexandre Lision51140e12013-12-02 10:54:09 -0500398 return &zrtpCommit;
399}
400
401ZrtpPacketCommit* ZRtp::prepareCommitMultiStream(ZrtpPacketHello *hello) {
402
403 randomZRTP(hvi, ZRTP_WORD_SIZE*4); // This is the Multi-Stream NONCE size
404
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500405 zrtpCommit.setZid(ownZid);
Alexandre Lision51140e12013-12-02 10:54:09 -0500406 zrtpCommit.setHashType((uint8_t*)hash->getName());
407 zrtpCommit.setCipherType((uint8_t*)cipher->getName());
408 zrtpCommit.setAuthLen((uint8_t*)authLength->getName());
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500409 zrtpCommit.setPubKeyType((uint8_t*)mult); // this is fixed because of Multi Stream mode
Alexandre Lision51140e12013-12-02 10:54:09 -0500410 zrtpCommit.setSasType((uint8_t*)sasType->getName());
411 zrtpCommit.setNonce(hvi);
412 zrtpCommit.setH2(H2);
413
414 int32_t len = zrtpCommit.getLength() * ZRTP_WORD_SIZE;
415
416 // Compute HMAC over Commit, excluding the HMAC field (HMAC_SIZE)
417 // and store in Hello. Key to HMAC is H1, use HASH_IMAGE_SIZE bytes only.
418 // Must use the implicit HMAC function.
419 uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];
420 uint32_t macLen;
421 hmacFunctionImpl(H1, HASH_IMAGE_SIZE, (uint8_t*)zrtpCommit.getHeaderBase(), len-(HMAC_SIZE), hmac, &macLen);
422 zrtpCommit.setHMACMulti(hmac);
423
424
425 // hash first messages to produce overall message hash
426 // First the Responder's Hello message, second the Commit
427 // (always Initator's).
428 // Must use the negotiated hash.
429 msgShaContext = createHashCtx();
430
431 int32_t helloLen = hello->getLength() * ZRTP_WORD_SIZE;
432 hashCtxFunction(msgShaContext, (unsigned char*)hello->getHeaderBase(), helloLen);
433 hashCtxFunction(msgShaContext, (unsigned char*)zrtpCommit.getHeaderBase(), len);
434
435 // store Hello data temporarily until we can check HMAC after receiving Commit as
436 // Responder or DHPart1 as Initiator
437 storeMsgTemp(hello);
438
Alexandre Lision51140e12013-12-02 10:54:09 -0500439 return &zrtpCommit;
440}
441
442/*
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500443 * At this point we will take the role of the Responder. We may have been in
Alexandre Lision51140e12013-12-02 10:54:09 -0500444 * the role of the Initiator before and already sent a commit packet that
445 * clashed with a commit packet from our peer. If our HVI was lower than our
446 * peer's HVI then we switched to Responder and handle our peer's commit packet
447 * here. This method takes care to delete and refresh data left over from a
448 * possible Initiator preparation. This belongs to prepared DH data, message
449 * hash SHA context
450 */
451ZrtpPacketDHPart* ZRtp::prepareDHPart1(ZrtpPacketCommit *commit, uint32_t* errMsg) {
452
453 sendInfo(Info, InfoRespCommitReceived);
454
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500455 // The following code check the hash chain according chapter 10 to detect
456 // false ZRTP packets.
Alexandre Lision51140e12013-12-02 10:54:09 -0500457 // Must use the implicit hash function.
458 uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];
459 memcpy(peerH2, commit->getH2(), HASH_IMAGE_SIZE);
460 hashFunctionImpl(peerH2, HASH_IMAGE_SIZE, tmpH3);
461
462 if (memcmp(tmpH3, peerH3, HASH_IMAGE_SIZE) != 0) {
463 *errMsg = IgnorePacket;
464 return NULL;
465 }
466
467 // Check HMAC of previous Hello packet stored in temporary buffer. The
468 // HMAC key of peer's Hello packet is peer's H2 that is contained in the
469 // Commit packet. Refer to chapter 9.1.
470 if (!checkMsgHmac(peerH2)) {
471 sendInfo(Severe, SevereHelloHMACFailed);
472 *errMsg = CriticalSWError;
473 return NULL;
474 }
475
476 // check if we support the commited Cipher type
477 AlgorithmEnum* cp = &zrtpSymCiphers.getByName((const char*)commit->getCipherType());
478 if (!cp->isValid()) { // no match - something went wrong
479 *errMsg = UnsuppCiphertype;
480 return NULL;
481 }
482 cipher = cp;
483
484 // check if we support the commited Authentication length
485 cp = &zrtpAuthLengths.getByName((const char*)commit->getAuthLen());
486 if (!cp->isValid()) { // no match - something went wrong
487 *errMsg = UnsuppSRTPAuthTag;
488 return NULL;
489 }
490 authLength = cp;
491
492 // check if we support the commited hash type
493 cp = &zrtpHashes.getByName((const char*)commit->getHashType());
494 if (!cp->isValid()) { // no match - something went wrong
495 *errMsg = UnsuppHashType;
496 return NULL;
497 }
498 // check if the peer's commited hash is the same that we used when
499 // preparing our commit packet. If not do the necessary resets and
500 // recompute some data.
501 if (*(int32_t*)(hash->getName()) != *(int32_t*)(cp->getName())) {
502 hash = cp;
503 setNegotiatedHash(hash);
Alexandre Lision51140e12013-12-02 10:54:09 -0500504 // Compute the Initator's and Responder's retained secret ids
505 // with the committed hash.
506 computeSharedSecretSet(zidRec);
507 }
Alexandre Lision51140e12013-12-02 10:54:09 -0500508 // check if we support the commited pub key type
509 cp = &zrtpPubKeys.getByName((const char*)commit->getPubKeysType());
510 if (!cp->isValid()) { // no match - something went wrong
511 *errMsg = UnsuppPKExchange;
512 return NULL;
513 }
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500514 if (*(int32_t*)(cp->getName()) == *(int32_t*)ec38) {
515 if (*(int32_t*)(hash->getName()) != *(int32_t*)s384) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500516 *errMsg = UnsuppHashType;
517 return NULL;
518 }
519 }
Alexandre Lision51140e12013-12-02 10:54:09 -0500520 pubKey = cp;
521
522 // check if we support the commited SAS type
523 cp = &zrtpSasTypes.getByName((const char*)commit->getSasType());
524 if (!cp->isValid()) { // no match - something went wrong
525 *errMsg = UnsuppSASScheme;
526 return NULL;
527 }
528 sasType = cp;
529
530 // dhContext cannot be NULL - always setup during prepareCommit()
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500531 // check if we can use the dhContext prepared by prepareCOmmit(),
Alexandre Lision51140e12013-12-02 10:54:09 -0500532 // if not delete old DH context and generate new one
533 // The algorithm names are 4 chars only, thus we can cast to int32_t
534 if (*(int32_t*)(dhContext->getDHtype()) != *(int32_t*)(pubKey->getName())) {
535 delete dhContext;
536 dhContext = new ZrtpDH(pubKey->getName());
537 dhContext->generatePublicKey();
538 }
539 sendInfo(Info, InfoDH1DHGenerated);
540
541 dhContext->getPubKeyBytes(pubKeyBytes);
542
543 // Setup a DHPart1 packet.
544 zrtpDH1.setPubKeyType(pubKey->getName());
545 zrtpDH1.setMessageType((uint8_t*)DHPart1Msg);
546 zrtpDH1.setRs1Id(rs1IDr);
547 zrtpDH1.setRs2Id(rs2IDr);
548 zrtpDH1.setAuxSecretId(auxSecretIDr);
549 zrtpDH1.setPbxSecretId(pbxSecretIDr);
550 zrtpDH1.setPv(pubKeyBytes);
551 zrtpDH1.setH1(H1);
552
553 int32_t len = zrtpDH1.getLength() * ZRTP_WORD_SIZE;
554
555 // Compute HMAC over DHPart1, excluding the HMAC field (HMAC_SIZE)
556 // and store in DHPart1.
557 // Use implicit Hash function
558 uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];
559 uint32_t macLen;
560 hmacFunctionImpl(H0, HASH_IMAGE_SIZE, (uint8_t*)zrtpDH1.getHeaderBase(), len-(HMAC_SIZE), hmac, &macLen);
561 zrtpDH1.setHMAC(hmac);
562
563 // We are definitly responder. Save the peer's hvi for later compare.
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500564 myRole = Responder;
Alexandre Lision51140e12013-12-02 10:54:09 -0500565 memcpy(peerHvi, commit->getHvi(), HVI_SIZE);
566
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500567 // We are responder. Release a possibly pre-computed SHA context
568 // because this was prepared for Initiator. Then create a new one.
Alexandre Lision51140e12013-12-02 10:54:09 -0500569 if (msgShaContext != NULL) {
570 closeHashCtx(msgShaContext, NULL);
571 }
572 msgShaContext = createHashCtx();
573
574 // Hash messages to produce overall message hash:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500575 // First the Responder's (my) Hello message, second the Commit
576 // (always Initator's), then the DH1 message (which is always a
577 // Responder's message).
578 // Must use negotiated hash
579 hashCtxFunction(msgShaContext, (unsigned char*)zrtpHello.getHeaderBase(), zrtpHello.getLength() * ZRTP_WORD_SIZE);
Alexandre Lision51140e12013-12-02 10:54:09 -0500580 hashCtxFunction(msgShaContext, (unsigned char*)commit->getHeaderBase(), commit->getLength() * ZRTP_WORD_SIZE);
581 hashCtxFunction(msgShaContext, (unsigned char*)zrtpDH1.getHeaderBase(), zrtpDH1.getLength() * ZRTP_WORD_SIZE);
582
583 // store Commit data temporarily until we can check HMAC after we got DHPart2
584 storeMsgTemp(commit);
585
586 return &zrtpDH1;
587}
588
589/*
590 * At this point we will take the role of the Initiator.
591 */
592ZrtpPacketDHPart* ZRtp::prepareDHPart2(ZrtpPacketDHPart *dhPart1, uint32_t* errMsg) {
593
594 uint8_t* pvr;
595
596 sendInfo(Info, InfoInitDH1Received);
597
598 // Because we are initiator the protocol engine didn't receive Commit
599 // thus could not store a peer's H2. A two step SHA256 is required to
600 // re-compute H3. Then compare with peer's H3 from peer's Hello packet.
601 // Must use implicit hash function.
602 uint8_t tmpHash[IMPL_MAX_DIGEST_LENGTH];
603 hashFunctionImpl(dhPart1->getH1(), HASH_IMAGE_SIZE, tmpHash); // Compute peer's H2
604 memcpy(peerH2, tmpHash, HASH_IMAGE_SIZE);
605 hashFunctionImpl(peerH2, HASH_IMAGE_SIZE, tmpHash); // Compute peer's H3 (tmpHash)
606
607 if (memcmp(tmpHash, peerH3, HASH_IMAGE_SIZE) != 0) {
608 *errMsg = IgnorePacket;
609 return NULL;
610 }
611
612 // Check HMAC of previous Hello packet stored in temporary buffer. The
613 // HMAC key of the Hello packet is peer's H2 that was computed above.
614 // Refer to chapter 9.1 and chapter 10.
615 if (!checkMsgHmac(peerH2)) {
616 sendInfo(Severe, SevereHelloHMACFailed);
617 *errMsg = CriticalSWError;
618 return NULL;
619 }
620
621 // get memory to store DH result TODO: make it fixed memory
622 DHss = new uint8_t[dhContext->getDhSize()];
623 if (DHss == NULL) {
624 *errMsg = CriticalSWError;
625 return NULL;
626 }
627
628 // get and check Responder's public value, see chap. 5.4.3 in the spec
629 pvr = dhPart1->getPv();
630 if (!dhContext->checkPubKey(pvr)) {
631 *errMsg = DHErrorWrongPV;
632 return NULL;
633 }
634 dhContext->computeSecretKey(pvr, DHss);
635
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500636 myRole = Initiator;
637
Alexandre Lision51140e12013-12-02 10:54:09 -0500638 // We are Initiator: the Responder's Hello and the Initiator's (our) Commit
639 // are already hashed in the context. Now hash the Responder's DH1 and then
640 // the Initiator's (our) DH2 in that order.
641 // Use the negotiated hash function.
642 hashCtxFunction(msgShaContext, (unsigned char*)dhPart1->getHeaderBase(), dhPart1->getLength() * ZRTP_WORD_SIZE);
643 hashCtxFunction(msgShaContext, (unsigned char*)zrtpDH2.getHeaderBase(), zrtpDH2.getLength() * ZRTP_WORD_SIZE);
644
645 // Compute the message Hash
646 closeHashCtx(msgShaContext, messageHash);
647 msgShaContext = NULL;
Alexandre Lision51140e12013-12-02 10:54:09 -0500648 // Now compute the S0, all dependend keys and the new RS1. The function
649 // also performs sign SAS callback if it's active.
650 generateKeysInitiator(dhPart1, zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -0500651
652 delete dhContext;
653 dhContext = NULL;
654
655 // TODO: at initiator we can call signSAS at this point, don't dealy until confirm1 reveived
656 // store DHPart1 data temporarily until we can check HMAC after receiving Confirm1
657 storeMsgTemp(dhPart1);
658 return &zrtpDH2;
659}
660
661/*
662 * At this point we are Responder.
663 */
664ZrtpPacketConfirm* ZRtp::prepareConfirm1(ZrtpPacketDHPart* dhPart2, uint32_t* errMsg) {
665
666 uint8_t* pvi;
667
668 sendInfo(Info, InfoRespDH2Received);
669
670 // Because we are responder we received a Commit and stored its H2.
671 // Now re-compute H2 from received H1 and compare with stored peer's H2.
672 // Use implicit hash function
673 uint8_t tmpHash[IMPL_MAX_DIGEST_LENGTH];
674 hashFunctionImpl(dhPart2->getH1(), HASH_IMAGE_SIZE, tmpHash);
675 if (memcmp(tmpHash, peerH2, HASH_IMAGE_SIZE) != 0) {
676 *errMsg = IgnorePacket;
677 return NULL;
678 }
679
680 // Check HMAC of Commit packet stored in temporary buffer. The
681 // HMAC key of the Commit packet is peer's H1 that is contained in
682 // DHPart2. Refer to chapter 9.1 and chapter 10.
683 if (!checkMsgHmac(dhPart2->getH1())) {
684 sendInfo(Severe, SevereCommitHMACFailed);
685 *errMsg = CriticalSWError;
686 return NULL;
687 }
688 // Now we have the peer's pvi. Because we are responder re-compute my hvi
689 // using my Hello packet and the Initiator's DHPart2 and compare with
690 // hvi sent in commit packet. If it doesn't macht then a MitM attack
691 // may have occured.
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500692 computeHvi(dhPart2, &zrtpHello);
Alexandre Lision51140e12013-12-02 10:54:09 -0500693 if (memcmp(hvi, peerHvi, HVI_SIZE) != 0) {
694 *errMsg = DHErrorWrongHVI;
695 return NULL;
696 }
697 DHss = new uint8_t[dhContext->getDhSize()];
698 if (DHss == NULL) {
699 *errMsg = CriticalSWError;
700 return NULL;
701 }
702 // Get and check the Initiator's public value, see chap. 5.4.2 of the spec
703 pvi = dhPart2->getPv();
704 if (!dhContext->checkPubKey(pvi)) {
705 *errMsg = DHErrorWrongPV;
706 return NULL;
707 }
708 dhContext->computeSecretKey(pvi, DHss);
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500709 // Hash the Initiator's DH2 into the message Hash (other messages already
710 // prepared, see method prepareDHPart1().
Alexandre Lision51140e12013-12-02 10:54:09 -0500711 // Use neotiated hash function
712 hashCtxFunction(msgShaContext, (unsigned char*)dhPart2->getHeaderBase(), dhPart2->getLength() * ZRTP_WORD_SIZE);
713
714 closeHashCtx(msgShaContext, messageHash);
715 msgShaContext = NULL;
Alexandre Lision51140e12013-12-02 10:54:09 -0500716 /*
717 * The expected shared secret Ids were already computed when we built the
718 * DHPart1 packet. Generate s0, all depended keys, and the new RS1 value
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500719 * for the ZID record. The functions also performs sign SAS callback if it's
720 * active. May reset the verify flag in ZID record.
Alexandre Lision51140e12013-12-02 10:54:09 -0500721 */
722 generateKeysResponder(dhPart2, zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -0500723
724 delete dhContext;
725 dhContext = NULL;
726
727 // Fill in Confirm1 packet.
728 zrtpConfirm1.setMessageType((uint8_t*)Confirm1Msg);
729
730 // Check if user verfied the SAS in a previous call and thus verfied
731 // the retained secret. Don't set the verified flag if paranoidMode is true.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500732 if (zidRec->isSasVerified() && !paranoidMode) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500733 zrtpConfirm1.setSASFlag();
734 }
735 zrtpConfirm1.setExpTime(0xFFFFFFFF);
736 zrtpConfirm1.setIv(randomIV);
737 zrtpConfirm1.setHashH0(H0);
738
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500739 // if this runs at PBX user agent enrollment service then set flag in confirm
Alexandre Lision51140e12013-12-02 10:54:09 -0500740 // packet and store the MitM key
741 if (enrollmentMode) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500742 // As clarification to RFC6189: store new PBX secret only if we don't have
743 // a matching PBX secret for the peer's ZID.
744 if (!peerIsEnrolled) {
745 computePBXSecret();
746 zidRec->setMiTMData(pbxSecretTmp);
747 }
748 // Set flag to enable user's client to ask for confirmation or re-confirmation.
Alexandre Lision51140e12013-12-02 10:54:09 -0500749 zrtpConfirm1.setPBXEnrollment();
Alexandre Lision51140e12013-12-02 10:54:09 -0500750 }
751 uint8_t confMac[MAX_DIGEST_LENGTH];
752 uint32_t macLen;
753
754 // Encrypt and HMAC with Responder's key - we are Respondere here
755 int hmlen = (zrtpConfirm1.getLength() - 9) * ZRTP_WORD_SIZE;
756 cipher->getEncrypt()(zrtpKeyR, cipher->getKeylen(), randomIV, zrtpConfirm1.getHashH0(), hmlen);
757 hmacFunction(hmacKeyR, hashLength, (unsigned char*)zrtpConfirm1.getHashH0(), hmlen, confMac, &macLen);
758
759 zrtpConfirm1.setHmac(confMac);
760
761 // store DHPart2 data temporarily until we can check HMAC after receiving Confirm2
762 storeMsgTemp(dhPart2);
763 return &zrtpConfirm1;
764}
765
766/*
767 * At this point we are Responder.
768 */
769ZrtpPacketConfirm* ZRtp::prepareConfirm1MultiStream(ZrtpPacketCommit* commit, uint32_t* errMsg) {
770
771 sendInfo(Info, InfoRespCommitReceived);
772
773 // The following code checks the hash chain according chapter 10 to detect
774 // false ZRTP packets.
775 // Use implicit hash function
776 uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];
777 memcpy(peerH2, commit->getH2(), HASH_IMAGE_SIZE);
778 hashFunctionImpl(peerH2, HASH_IMAGE_SIZE, tmpH3);
779
780 if (memcmp(tmpH3, peerH3, HASH_IMAGE_SIZE) != 0) {
781 *errMsg = IgnorePacket;
782 return NULL;
783 }
784
785 // Check HMAC of previous Hello packet stored in temporary buffer. The
786 // HMAC key of peer's Hello packet is peer's H2 that is contained in the
787 // Commit packet. Refer to chapter 9.1.
788 if (!checkMsgHmac(peerH2)) {
789 sendInfo(Severe, SevereHelloHMACFailed);
790 *errMsg = CriticalSWError;
791 return NULL;
792 }
793
794 // check if Commit contains "Mult" as pub key type
795 AlgorithmEnum* cp = &zrtpPubKeys.getByName((const char*)commit->getPubKeysType());
796 if (!cp->isValid() || *(int32_t*)(cp->getName()) != *(int32_t*)mult) {
797 *errMsg = UnsuppPKExchange;
798 return NULL;
799 }
800
801 // check if we support the commited cipher
802 cp = &zrtpSymCiphers.getByName((const char*)commit->getCipherType());
803 if (!cp->isValid()) { // no match - something went wrong
804 *errMsg = UnsuppCiphertype;
805 return NULL;
806 }
807 cipher = cp;
808
809 // check if we support the commited Authentication length
810 cp = &zrtpAuthLengths.getByName((const char*)commit->getAuthLen());
811 if (!cp->isValid()) { // no match - something went wrong
812 *errMsg = UnsuppSRTPAuthTag;
813 return NULL;
814 }
815 authLength = cp;
816
817 // check if we support the commited hash type
818 cp = &zrtpHashes.getByName((const char*)commit->getHashType());
819 if (!cp->isValid()) { // no match - something went wrong
820 *errMsg = UnsuppHashType;
821 return NULL;
822 }
823 // check if the peer's commited hash is the same that we used when
824 // preparing our commit packet. If not do the necessary resets and
825 // recompute some data.
826 if (*(int32_t*)(hash->getName()) != *(int32_t*)(cp->getName())) {
827 hash = cp;
828 setNegotiatedHash(hash);
829 }
830 myRole = Responder;
831
832 // We are responder. Release a possibly pre-computed SHA256 context
833 // because this was prepared for Initiator. Then create a new one.
834 if (msgShaContext != NULL) {
835 closeHashCtx(msgShaContext, NULL);
836 }
837 msgShaContext = createHashCtx();
838
839 // Hash messages to produce overall message hash:
840 // First the Responder's (my) Hello message, second the Commit
841 // (always Initator's)
842 // use negotiated hash
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500843 hashCtxFunction(msgShaContext, (unsigned char*)zrtpHello.getHeaderBase(), zrtpHello.getLength() * ZRTP_WORD_SIZE);
Alexandre Lision51140e12013-12-02 10:54:09 -0500844 hashCtxFunction(msgShaContext, (unsigned char*)commit->getHeaderBase(), commit->getLength() * ZRTP_WORD_SIZE);
845
846 closeHashCtx(msgShaContext, messageHash);
847 msgShaContext = NULL;
848
849 generateKeysMultiStream();
850
851 // Fill in Confirm1 packet.
852 zrtpConfirm1.setMessageType((uint8_t*)Confirm1Msg);
853 zrtpConfirm1.setExpTime(0xFFFFFFFF);
854 zrtpConfirm1.setIv(randomIV);
855 zrtpConfirm1.setHashH0(H0);
856
857 uint8_t confMac[MAX_DIGEST_LENGTH];
858 uint32_t macLen;
859
860 // Encrypt and HMAC with Responder's key - we are Respondere here
861 int32_t hmlen = (zrtpConfirm1.getLength() - 9) * ZRTP_WORD_SIZE;
862 cipher->getEncrypt()(zrtpKeyR, cipher->getKeylen(), randomIV, zrtpConfirm1.getHashH0(), hmlen);
863
864 // Use negotiated HMAC (hash)
865 hmacFunction(hmacKeyR, hashLength, (unsigned char*)zrtpConfirm1.getHashH0(), hmlen, confMac, &macLen);
866
867 zrtpConfirm1.setHmac(confMac);
868
869 // Store Commit data temporarily until we can check HMAC after receiving Confirm2
870 storeMsgTemp(commit);
871 return &zrtpConfirm1;
872}
873
874/*
875 * At this point we are Initiator.
876 */
877ZrtpPacketConfirm* ZRtp::prepareConfirm2(ZrtpPacketConfirm* confirm1, uint32_t* errMsg) {
878
879 sendInfo(Info, InfoInitConf1Received);
880
881 uint8_t confMac[MAX_DIGEST_LENGTH];
882 uint32_t macLen;
883
884 // Use the Responder's keys here because we are Initiator here and
885 // receive packets from Responder
886 int16_t hmlen = (confirm1->getLength() - 9) * ZRTP_WORD_SIZE;
887
888 // Use negotiated HMAC (hash)
889 hmacFunction(hmacKeyR, hashLength, (unsigned char*)confirm1->getHashH0(), hmlen, confMac, &macLen);
890
891 if (memcmp(confMac, confirm1->getHmac(), HMAC_SIZE) != 0) {
892 *errMsg = ConfirmHMACWrong;
893 return NULL;
894 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500895 cipher->getDecrypt()(zrtpKeyR, cipher->getKeylen(), (uint8_t*)confirm1->getIv(), confirm1->getHashH0(), hmlen);
Alexandre Lision51140e12013-12-02 10:54:09 -0500896
897 // Check HMAC of DHPart1 packet stored in temporary buffer. The
898 // HMAC key of the DHPart1 packet is peer's H0 that is contained in
899 // Confirm1. Refer to chapter 9.
900 if (!checkMsgHmac(confirm1->getHashH0())) {
901 sendInfo(Severe, SevereDH1HMACFailed);
902 *errMsg = CriticalSWError;
903 return NULL;
904 }
905 signatureLength = confirm1->getSignatureLength();
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500906 if (signSasSeen && signatureLength > 0) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500907 signatureData = confirm1->getSignatureData();
908 callback->checkSASSignature(sasHash);
909 // TODO: error handling if checkSASSignature returns false.
910 }
911 /*
912 * The Confirm1 is ok, handle the Retained secret stuff and inform
913 * GUI about state.
914 */
915 bool sasFlag = confirm1->isSASFlag();
916
Alexandre Lision51140e12013-12-02 10:54:09 -0500917 // Our peer did not confirm the SAS in last session, thus reset
918 // our SAS flag too. Reset the flag also if paranoidMode is true.
919 if (!sasFlag || paranoidMode) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500920 zidRec->resetSasVerified();
Alexandre Lision51140e12013-12-02 10:54:09 -0500921 }
922 // get verified flag from current RS1 before set a new RS1. This
923 // may not be set even if peer's flag is set in confirm1 message.
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500924 sasFlag = zidRec->isSasVerified();
Alexandre Lision51140e12013-12-02 10:54:09 -0500925
926 // now we are ready to save the new RS1 which inherits the verified
927 // flag from old RS1
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500928 zidRec->setNewRs1((const uint8_t*)newRs1);
Alexandre Lision51140e12013-12-02 10:54:09 -0500929
930 // now generate my Confirm2 message
931 zrtpConfirm2.setMessageType((uint8_t*)Confirm2Msg);
932 zrtpConfirm2.setHashH0(H0);
933
934 if (sasFlag) {
935 zrtpConfirm2.setSASFlag();
936 }
937 zrtpConfirm2.setExpTime(0xFFFFFFFF);
938 zrtpConfirm2.setIv(randomIV);
939
940 // Compute PBX secret if we are in enrollemnt mode (PBX user agent)
941 // or enrollment was enabled at normal user agent and flag in confirm packet
942 if (enrollmentMode || (enableMitmEnrollment && confirm1->isPBXEnrollment())) {
943 computePBXSecret();
944
945 // if this runs at PBX user agent enrollment service then set flag in confirm
946 // packet and store the MitM key. The PBX user agent service always stores
947 // its MitM key.
948 if (enrollmentMode) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500949 // As clarification to RFC6189: store new PBX secret only if we don't have
950 // a matching PBX secret for the peer's ZID.
951 if (!peerIsEnrolled) {
952 computePBXSecret();
953 zidRec->setMiTMData(pbxSecretTmp);
954 }
955 // Set flag to enable user's client to ask for confirmation or re-confirmation.
Alexandre Lision51140e12013-12-02 10:54:09 -0500956 zrtpConfirm2.setPBXEnrollment();
Alexandre Lision51140e12013-12-02 10:54:09 -0500957 }
958 }
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500959 getZidCacheInstance()->saveRecord(zidRec);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500960
Alexandre Lision51140e12013-12-02 10:54:09 -0500961 // Encrypt and HMAC with Initiator's key - we are Initiator here
962 hmlen = (zrtpConfirm2.getLength() - 9) * ZRTP_WORD_SIZE;
963 cipher->getEncrypt()(zrtpKeyI, cipher->getKeylen(), randomIV, zrtpConfirm2.getHashH0(), hmlen);
964
965 // Use negotiated HMAC (hash)
966 hmacFunction(hmacKeyI, hashLength, (unsigned char*)zrtpConfirm2.getHashH0(), hmlen, confMac, &macLen);
967
968 zrtpConfirm2.setHmac(confMac);
969
970 // Ask for enrollment only if enabled via configuration and the
971 // confirm1 packet contains the enrollment flag. The enrolling user
972 // agent stores the MitM key only if the user accepts the enrollment
973 // request.
974 if (enableMitmEnrollment && confirm1->isPBXEnrollment()) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500975 // As clarification to RFC6189: if already enrolled (having a matching PBX secret)
976 // ask for reconfirmation.
977 if (!peerIsEnrolled) {
978 callback->zrtpAskEnrollment(EnrollmentRequest);
979 }
980 else {
981 callback->zrtpAskEnrollment(EnrollmentReconfirm);
982 }
Alexandre Lision51140e12013-12-02 10:54:09 -0500983 }
984 return &zrtpConfirm2;
985}
986
Alexandre Lision51140e12013-12-02 10:54:09 -0500987/*
988 * At this point we are Initiator.
989 */
990ZrtpPacketConfirm* ZRtp::prepareConfirm2MultiStream(ZrtpPacketConfirm* confirm1, uint32_t* errMsg) {
991
992 // check Confirm1 packet using the keys
993 // prepare Confirm2 packet
994 // don't update SAS, RS
995 sendInfo(Info, InfoInitConf1Received);
996
997 uint8_t confMac[MAX_DIGEST_LENGTH];
998 uint32_t macLen;
999
1000 closeHashCtx(msgShaContext, messageHash);
1001 msgShaContext = NULL;
1002 myRole = Initiator;
1003
1004 generateKeysMultiStream();
1005
1006 // Use the Responder's keys here because we are Initiator here and
1007 // receive packets from Responder
1008 int32_t hmlen = (confirm1->getLength() - 9) * ZRTP_WORD_SIZE;
1009
1010 // Use negotiated HMAC (hash)
1011 hmacFunction(hmacKeyR, hashLength, (unsigned char*)confirm1->getHashH0(), hmlen, confMac, &macLen);
1012
1013 if (memcmp(confMac, confirm1->getHmac(), HMAC_SIZE) != 0) {
1014 *errMsg = ConfirmHMACWrong;
1015 return NULL;
1016 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001017 // Cast away the const for the IV - the standalone AES CFB modifies IV on return
1018 cipher->getDecrypt()(zrtpKeyR, cipher->getKeylen(), (uint8_t*)confirm1->getIv(), confirm1->getHashH0(), hmlen);
Alexandre Lision51140e12013-12-02 10:54:09 -05001019
1020 // Because we are initiator the protocol engine didn't receive Commit and
1021 // because we are using multi-stream mode here we also did not receive a DHPart1 and
1022 // thus could not store a responder's H2 or H1. A two step hash is required to
1023 // re-compute H1, H2.
1024 // USe implicit hash function.
1025 uint8_t tmpHash[IMPL_MAX_DIGEST_LENGTH];
1026 hashFunctionImpl(confirm1->getHashH0(), HASH_IMAGE_SIZE, tmpHash); // Compute peer's H1 in tmpHash
1027 hashFunctionImpl(tmpHash, HASH_IMAGE_SIZE, tmpHash); // Compute peer's H2 in tmpHash
1028 memcpy(peerH2, tmpHash, HASH_IMAGE_SIZE); // copy and truncate to peerH2
1029
1030 // Check HMAC of previous Hello packet stored in temporary buffer. The
1031 // HMAC key of the Hello packet is peer's H2 that was computed above.
1032 // Refer to chapter 9.1 and chapter 10.
1033 if (!checkMsgHmac(peerH2)) {
1034 sendInfo(Severe, SevereHelloHMACFailed);
1035 *errMsg = CriticalSWError;
1036 return NULL;
1037 }
Alexandre Lision51140e12013-12-02 10:54:09 -05001038 // now generate my Confirm2 message
1039 zrtpConfirm2.setMessageType((uint8_t*)Confirm2Msg);
1040 zrtpConfirm2.setHashH0(H0);
1041 zrtpConfirm2.setExpTime(0xFFFFFFFF);
1042 zrtpConfirm2.setIv(randomIV);
1043
1044 // Encrypt and HMAC with Initiator's key - we are Initiator here
1045 hmlen = (zrtpConfirm2.getLength() - 9) * ZRTP_WORD_SIZE;
1046 cipher->getEncrypt()(zrtpKeyI, cipher->getKeylen(), randomIV, zrtpConfirm2.getHashH0(), hmlen);
1047
1048 // Use negotiated HMAC (hash)
1049 hmacFunction(hmacKeyI, hashLength, (unsigned char*)zrtpConfirm2.getHashH0(), hmlen, confMac, &macLen);
1050
1051 zrtpConfirm2.setHmac(confMac);
1052 return &zrtpConfirm2;
1053}
1054
1055/*
1056 * At this point we are Responder.
1057 */
1058ZrtpPacketConf2Ack* ZRtp::prepareConf2Ack(ZrtpPacketConfirm *confirm2, uint32_t* errMsg) {
1059
1060 sendInfo(Info, InfoRespConf2Received);
1061
1062 uint8_t confMac[MAX_DIGEST_LENGTH];
1063 uint32_t macLen;
1064
1065 // Use the Initiator's keys here because we are Responder here and
1066 // reveice packets from Initiator
1067 int16_t hmlen = (confirm2->getLength() - 9) * ZRTP_WORD_SIZE;
1068
1069 // Use negotiated HMAC (hash)
1070 hmacFunction(hmacKeyI, hashLength,
1071 (unsigned char*)confirm2->getHashH0(),
1072 hmlen, confMac, &macLen);
1073
1074 if (memcmp(confMac, confirm2->getHmac(), HMAC_SIZE) != 0) {
1075 *errMsg = ConfirmHMACWrong;
1076 return NULL;
1077 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001078 // Cast away the const for the IV - the standalone AES CFB modifies IV on return
1079 cipher->getDecrypt()(zrtpKeyI, cipher->getKeylen(), (uint8_t*)confirm2->getIv(), confirm2->getHashH0(), hmlen);
Alexandre Lision51140e12013-12-02 10:54:09 -05001080
1081 if (!multiStream) {
1082 // Check HMAC of DHPart2 packet stored in temporary buffer. The
1083 // HMAC key of the DHPart2 packet is peer's H0 that is contained in
1084 // Confirm2. Refer to chapter 9.1 and chapter 10.
1085 if (!checkMsgHmac(confirm2->getHashH0())) {
1086 sendInfo(Severe, SevereDH2HMACFailed);
1087 *errMsg = CriticalSWError;
1088 return NULL;
1089 }
1090 signatureLength = confirm2->getSignatureLength();
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001091 if (signSasSeen && signatureLength > 0) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001092 signatureData = confirm2->getSignatureData();
1093 callback->checkSASSignature(sasHash);
1094 // TODO: error handling if checkSASSignature returns false.
1095 }
1096 /*
1097 * The Confirm2 is ok, handle the Retained secret stuff and inform
1098 * GUI about state.
1099 */
1100 bool sasFlag = confirm2->isSASFlag();
Alexandre Lision51140e12013-12-02 10:54:09 -05001101 // Our peer did not confirm the SAS in last session, thus reset
1102 // our SAS flag too. Reset the flag also if paranoidMode is true.
1103 if (!sasFlag || paranoidMode) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001104 zidRec->resetSasVerified();
Alexandre Lision51140e12013-12-02 10:54:09 -05001105 }
1106
Alexandre Lision51140e12013-12-02 10:54:09 -05001107 // save new RS1, this inherits the verified flag from old RS1
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001108 zidRec->setNewRs1((const uint8_t*)newRs1);
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001109 getZidCacheInstance()->saveRecord(zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -05001110
1111 // Ask for enrollment only if enabled via configuration and the
1112 // confirm packet contains the enrollment flag. The enrolling user
1113 // agent stores the MitM key only if the user accepts the enrollment
1114 // request.
1115 if (enableMitmEnrollment && confirm2->isPBXEnrollment()) {
1116 computePBXSecret();
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001117 // As clarification to RFC6189: if already enrolled (having a matching PBX secret)
1118 // ask for reconfirmation.
1119 if (!peerIsEnrolled) {
1120 callback->zrtpAskEnrollment(EnrollmentRequest);
1121 }
1122 else {
1123 callback->zrtpAskEnrollment(EnrollmentReconfirm);
1124 }
Alexandre Lision51140e12013-12-02 10:54:09 -05001125 }
1126 }
1127 else {
1128 // Check HMAC of Commit packet stored in temporary buffer. The
1129 // HMAC key of the Commit packet is initiator's H1
1130 // use implicit hash function.
1131 uint8_t tmpHash[IMPL_MAX_DIGEST_LENGTH];
1132 hashFunctionImpl(confirm2->getHashH0(), HASH_IMAGE_SIZE, tmpHash); // Compute initiator's H1 in tmpHash
1133
1134 if (!checkMsgHmac(tmpHash)) {
1135 sendInfo(Severe, SevereCommitHMACFailed);
1136 *errMsg = CriticalSWError;
1137 return NULL;
1138 }
Alexandre Lision51140e12013-12-02 10:54:09 -05001139 }
1140 return &zrtpConf2Ack;
1141}
1142
1143ZrtpPacketErrorAck* ZRtp::prepareErrorAck(ZrtpPacketError* epkt) {
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001144 sendInfo(ZrtpError, epkt->getErrorCode() * -1);
Alexandre Lision51140e12013-12-02 10:54:09 -05001145 return &zrtpErrorAck;
1146}
1147
1148ZrtpPacketError* ZRtp::prepareError(uint32_t errMsg) {
1149 zrtpError.setErrorCode(errMsg);
1150 return &zrtpError;
1151}
1152
1153ZrtpPacketPingAck* ZRtp::preparePingAck(ZrtpPacketPing* ppkt) {
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001154
Alexandre Lision51140e12013-12-02 10:54:09 -05001155 // Because we do not support ZRTP proxy mode use the truncated ZID.
1156 // If this code shall be used in ZRTP proxy implementation the computation
1157 // of the endpoint hash must be enhanced (see chaps 5.15ff and 5.16)
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001158 zrtpPingAck.setLocalEpHash(ownZid);
Alexandre Lision51140e12013-12-02 10:54:09 -05001159 zrtpPingAck.setRemoteEpHash(ppkt->getEpHash());
1160 zrtpPingAck.setSSRC(peerSSRC);
1161 return &zrtpPingAck;
1162}
1163
1164ZrtpPacketRelayAck* ZRtp::prepareRelayAck(ZrtpPacketSASrelay* srly, uint32_t* errMsg) {
1165 // handle and render SAS relay data only if the peer announced that it is a trusted
1166 // PBX. Don't handle SAS relay in paranoidMode.
1167 if (!mitmSeen || paranoidMode)
1168 return &zrtpRelayAck;
1169
1170 uint8_t* hkey, *ekey;
1171 // If we are responder then the PBX used it's Initiator keys
1172 if (myRole == Responder) {
1173 hkey = hmacKeyI;
1174 ekey = zrtpKeyI;
1175 }
1176 else {
1177 hkey = hmacKeyR;
1178 ekey = zrtpKeyR;
1179 }
1180
1181 uint8_t confMac[MAX_DIGEST_LENGTH];
1182 uint32_t macLen;
1183
Alexandre Lision51140e12013-12-02 10:54:09 -05001184 int16_t hmlen = (srly->getLength() - 9) * ZRTP_WORD_SIZE;
1185
1186 // Use negotiated HMAC (hash)
1187 hmacFunction(hkey, hashLength, (unsigned char*)srly->getFiller(), hmlen, confMac, &macLen);
1188
1189 if (memcmp(confMac, srly->getHmac(), HMAC_SIZE) != 0) {
1190 *errMsg = ConfirmHMACWrong;
1191 return NULL; // TODO - check error handling
1192 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001193 // Cast away the const for the IV - the standalone AES CFB modifies IV on return
1194 cipher->getDecrypt()(ekey, cipher->getKeylen(), (uint8_t*)srly->getIv(), (uint8_t*)srly->getFiller(), hmlen);
Alexandre Lision51140e12013-12-02 10:54:09 -05001195
Alexandre Lision51140e12013-12-02 10:54:09 -05001196 const uint8_t* newSasHash = srly->getTrustedSas();
Alexandre Lision51140e12013-12-02 10:54:09 -05001197 bool sasHashNull = true;
1198 for (int i = 0; i < HASH_IMAGE_SIZE; i++) {
1199 if (newSasHash[i] != 0) {
1200 sasHashNull = false;
1201 break;
1202 }
1203 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001204 std::string cs(cipher->getReadable());
1205 cs.append("/").append(pubKey->getName());
1206
Alexandre Lision51140e12013-12-02 10:54:09 -05001207 // Check if new SAS is null or a trusted MitM relationship doesn't exist.
1208 // If this is the case then don't render and don't show the new SAS - use
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001209 // our computed SAS hash but we may use a different SAS rendering algorithm to
Alexandre Lision51140e12013-12-02 10:54:09 -05001210 // render the computed SAS.
1211 if (sasHashNull || !peerIsEnrolled) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001212 cs.append("/MitM");
Alexandre Lision51140e12013-12-02 10:54:09 -05001213 newSasHash = sasHash;
1214 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001215 else {
1216 cs.append("/SASviaMitM");
1217 }
Alexandre Lision51140e12013-12-02 10:54:09 -05001218 // If other SAS schemes required - check here and use others
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001219 const uint8_t* render = srly->getSasAlgo();
Alexandre Lision51140e12013-12-02 10:54:09 -05001220 AlgorithmEnum* renderAlgo = &zrtpSasTypes.getByName((const char*)render);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001221 uint8_t sasBytes[4];
Alexandre Lision51140e12013-12-02 10:54:09 -05001222 if (renderAlgo->isValid()) {
1223 sasBytes[0] = newSasHash[0];
1224 sasBytes[1] = newSasHash[1];
1225 sasBytes[2] = newSasHash[2] & 0xf0;
1226 sasBytes[3] = 0;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001227 if (*(int32_t*)b32 == *(int32_t*)(renderAlgo->getName())) {
1228 SAS = Base32(sasBytes, 20).getEncoded();
1229 }
1230 else {
1231 SAS.assign(sas256WordsEven[sasBytes[0]]).append(":").append(sas256WordsOdd[sasBytes[1]]);
1232 }
Alexandre Lision51140e12013-12-02 10:54:09 -05001233 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001234 bool verify = zidRec->isSasVerified() && srly->isSASFlag();
1235 callback->srtpSecretsOn(cs, SAS, verify);
Alexandre Lision51140e12013-12-02 10:54:09 -05001236 return &zrtpRelayAck;
1237}
1238
1239// TODO Implement GoClear handling
1240ZrtpPacketClearAck* ZRtp::prepareClearAck(ZrtpPacketGoClear* gpkt) {
1241 sendInfo(Warning, WarningGoClearReceived);
1242 return &zrtpClearAck;
1243}
1244
1245ZrtpPacketGoClear* ZRtp::prepareGoClear(uint32_t errMsg) {
1246 ZrtpPacketGoClear* gclr = &zrtpGoClear;
1247 gclr->clrClearHmac();
1248 return gclr;
1249}
1250
1251/*
1252 * The next functions look up and return a prefered algorithm. These
1253 * functions work as follows:
1254 * - If the Hello packet does not contain an algorithm (number of algorithms
1255* is zero) then return the mandatory algorithm.
1256 * - Build a list of algorithm names and ids from configuration data. If
1257 * the configuration data does not contain a mandatory algorithm append
1258 * the mandatory algorithm to the list and ids.
1259 * - Build a list of algorithm names from the Hello message. If
1260 * the Hello message does not contain a mandatory algorithm append
1261 * the mandatory algorithm to the list.
1262 * - Lookup a matching algorithm. The list built from Hello takes
1263 * precedence in the lookup (indexed by the outermost loop).
1264 *
1265 * This guarantees that we always return a supported alogrithm respecting
1266 * the order of algorithms in the Hello message
1267 *
1268 * The mandatory algorithms are: (internal enums are our prefered algoritms)
1269 * Hash: S256 (SHA 256) (internal enum Sha256)
1270 * Symmetric Cipher: AES1 (AES 128) (internal enum Aes128)
1271 * SRTP Authentication: HS32 and HS80 (32/80 bits) (internal enum AuthLen32)
1272 * Key Agreement: DH3k (3072 Diffie-Helman) (internal enum Dh3072)
1273 *
1274 */
1275AlgorithmEnum* ZRtp::findBestHash(ZrtpPacketHello *hello) {
1276
1277 int i;
1278 int ii;
1279 int numAlgosOffered;
1280 AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+1];
1281
1282 int numAlgosConf;
1283 AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
1284
Alexandre Lision51140e12013-12-02 10:54:09 -05001285 // If Hello does not contain any hash names return Sha256, its mandatory
1286 int num = hello->getNumHashes();
1287 if (num == 0) {
1288 return &zrtpHashes.getByName(mandatoryHash);
1289 }
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001290 // Build list of configured hash algorithm names, append mandatory algos
1291 // if necessary.
Alexandre Lision51140e12013-12-02 10:54:09 -05001292 numAlgosConf = configureAlgos.getNumConfiguredAlgos(HashAlgorithm);
1293 for (i = 0; i < numAlgosConf; i++) {
1294 algosConf[i] = &configureAlgos.getAlgoAt(HashAlgorithm, i);
Alexandre Lision51140e12013-12-02 10:54:09 -05001295 }
1296
1297 // Build list of offered known algos in Hello, append mandatory algos if necessary
Alexandre Lision51140e12013-12-02 10:54:09 -05001298 for (numAlgosOffered = 0, i = 0; i < num; i++) {
1299 algosOffered[numAlgosOffered] = &zrtpHashes.getByName((const char*)hello->getHashType(i));
1300 if (!algosOffered[numAlgosOffered]->isValid())
1301 continue;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001302 numAlgosOffered++;
Alexandre Lision51140e12013-12-02 10:54:09 -05001303 }
1304
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001305 // Lookup offered algos in configured algos. Because of appended
1306 // mandatory algorithms at least one match will happen
Alexandre Lision51140e12013-12-02 10:54:09 -05001307 for (i = 0; i < numAlgosOffered; i++) {
1308 for (ii = 0; ii < numAlgosConf; ii++) {
1309 if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
1310 return algosConf[ii];
1311 }
1312 }
1313 }
1314 return &zrtpHashes.getByName(mandatoryHash);
1315}
1316
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001317
Alexandre Lision51140e12013-12-02 10:54:09 -05001318AlgorithmEnum* ZRtp::findBestCipher(ZrtpPacketHello *hello, AlgorithmEnum* pk) {
1319
1320 int i;
1321 int ii;
1322 int numAlgosOffered;
1323 AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+1];
1324
1325 int numAlgosConf;
1326 AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
1327
Alexandre Lision51140e12013-12-02 10:54:09 -05001328 int num = hello->getNumCiphers();
1329 if (num == 0 || (*(int32_t*)(pk->getName()) == *(int32_t*)dh2k)) {
1330 return &zrtpSymCiphers.getByName(aes1);
1331 }
1332
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001333 // Build list of configured cipher algorithm names.
Alexandre Lision51140e12013-12-02 10:54:09 -05001334 numAlgosConf = configureAlgos.getNumConfiguredAlgos(CipherAlgorithm);
1335 for (i = 0; i < numAlgosConf; i++) {
1336 algosConf[i] = &configureAlgos.getAlgoAt(CipherAlgorithm, i);
Alexandre Lision51140e12013-12-02 10:54:09 -05001337 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001338 // Build list of offered known algos names in Hello.
Alexandre Lision51140e12013-12-02 10:54:09 -05001339 for (numAlgosOffered = 0, i = 0; i < num; i++) {
1340 algosOffered[numAlgosOffered] = &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));
1341 if (!algosOffered[numAlgosOffered]->isValid())
1342 continue;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001343 numAlgosOffered++;
Alexandre Lision51140e12013-12-02 10:54:09 -05001344 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001345 // Lookup offered algos in configured algos. Prefer algorithms that appear first in Hello packet (offered).
Alexandre Lision51140e12013-12-02 10:54:09 -05001346 for (i = 0; i < numAlgosOffered; i++) {
1347 for (ii = 0; ii < numAlgosConf; ii++) {
1348 if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
1349 return algosConf[ii];
1350 }
1351 }
1352 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001353 // If we don't have a match - use the mandatory algorithm
Alexandre Lision51140e12013-12-02 10:54:09 -05001354 return &zrtpSymCiphers.getByName(mandatoryCipher);
1355}
1356
1357AlgorithmEnum* ZRtp::findBestPubkey(ZrtpPacketHello *hello) {
1358
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001359 int i;
1360 int ii;
1361 int numAlgosIntersect;
1362 AlgorithmEnum* algosIntersect[ZrtpConfigure::maxNoOfAlgos+1];
1363
1364 int numAlgosConf;
1365 AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
Alexandre Lision51140e12013-12-02 10:54:09 -05001366
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001367 // Build list of own pubkey algorithm names, must follow the order
1368 // defined in RFC 6189, chapter 4.1.2.
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001369 const char *orderedAlgos[] = {dh2k, ec25, dh3k, ec38};
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001370 int numOrderedAlgos = sizeof(orderedAlgos) / sizeof(const char*);
Alexandre Lision51140e12013-12-02 10:54:09 -05001371
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001372 int num = hello->getNumPubKeys();
1373 if (num == 0) {
1374 hash = &zrtpHashes.getByName(mandatoryHash); // set mandatory hash
Alexandre Lision51140e12013-12-02 10:54:09 -05001375 return &zrtpPubKeys.getByName(mandatoryPubKey);
1376 }
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001377 // The list must include real public key algorithms only, so skip
1378 // mult-stream mode, preshared and alike.
1379 numAlgosConf = configureAlgos.getNumConfiguredAlgos(PubKeyAlgorithm);
1380 for (i = 0, ii = 0; i < numAlgosConf; i++) {
1381 algosConf[ii] = &configureAlgos.getAlgoAt(PubKeyAlgorithm, ii);
1382 if (*(int32_t*)(algosConf[ii]->getName()) == *(int32_t*)mult) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001383 continue; // skip multi-stream mode
1384 }
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001385 ii++;
1386 }
1387 numAlgosConf = ii;
1388
1389 // Build list of intersecting algos: own and offered in Hello, intersect list is ordered according to offered algorithms
1390 for (numAlgosIntersect = 0, i = 0; i < num; i++) {
1391 for (ii = 0; ii < numAlgosConf; ii++) {
1392 algosIntersect[numAlgosIntersect] = &zrtpPubKeys.getByName((const char*)hello->getPubKeyType(i));
1393 if (*(int32_t*)(algosConf[ii]->getName()) == *(int32_t*)(algosIntersect[numAlgosIntersect]->getName())) {
1394 numAlgosIntersect++;
Alexandre Lision51140e12013-12-02 10:54:09 -05001395 }
1396 }
1397 }
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001398 if (numAlgosIntersect == 0) {
1399 // If we don't find a common algorithm - use the mandatory algorithms
1400 hash = &zrtpHashes.getByName(mandatoryHash);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001401 return &zrtpPubKeys.getByName(mandatoryPubKey);
1402 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001403 AlgorithmEnum* useAlgo;
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001404 if (numAlgosIntersect > 1 && *(int32_t*)(algosConf[0]->getName()) != *(int32_t*)(algosIntersect[0]->getName())) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001405 int own, peer;
1406
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001407 const int32_t *name = (int32_t*)algosConf[0]->getName();
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001408 for (own = 0; own < numOrderedAlgos; own++) {
1409 if (*name == *(int32_t*)orderedAlgos[own])
1410 break;
1411 }
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001412 name = (int32_t*)algosIntersect[0]->getName();
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001413 for (peer = 0; peer < numOrderedAlgos; peer++) {
1414 if (*name == *(int32_t*)orderedAlgos[peer])
1415 break;
1416 }
1417 if (own < peer) {
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001418 useAlgo = algosConf[0];
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001419 }
1420 else {
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001421 useAlgo = algosIntersect[0];
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001422 }
1423 // find fastest of conf vs intersecting
1424 }
1425 else {
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001426 useAlgo = algosIntersect[0];
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001427 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001428 // select a corresponding strong hash if necessary.
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001429 if (*(int32_t*)(useAlgo->getName()) == *(int32_t*)ec38) {
1430 hash = getStrongHashOffered(hello);
1431 cipher = getStrongCipherOffered(hello);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001432 }
1433 else {
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001434 hash = findBestHash(hello);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001435 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001436 return useAlgo;
Alexandre Lision51140e12013-12-02 10:54:09 -05001437}
1438
1439AlgorithmEnum* ZRtp::findBestSASType(ZrtpPacketHello *hello) {
1440
1441 int i;
1442 int ii;
1443 int numAlgosOffered;
1444 AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+1];
1445
1446 int numAlgosConf;
1447 AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
1448
Alexandre Lision51140e12013-12-02 10:54:09 -05001449 int num = hello->getNumSas();
1450 if (num == 0) {
1451 return &zrtpSasTypes.getByName(mandatorySasType);
1452 }
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001453 // Buildlist of configured SAS algorithm names
Alexandre Lision51140e12013-12-02 10:54:09 -05001454 numAlgosConf = configureAlgos.getNumConfiguredAlgos(SasType);
1455 for (i = 0; i < numAlgosConf; i++) {
1456 algosConf[i] = &configureAlgos.getAlgoAt(SasType, i);
Alexandre Lision51140e12013-12-02 10:54:09 -05001457 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001458 // Build list of offered known algos in Hello,
Alexandre Lision51140e12013-12-02 10:54:09 -05001459 for (numAlgosOffered = 0, i = 0; i < num; i++) {
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001460 algosOffered[numAlgosOffered] = &zrtpSasTypes.getByName((const char*)hello->getSasType(i++));
Alexandre Lision51140e12013-12-02 10:54:09 -05001461 if (!algosOffered[numAlgosOffered]->isValid())
1462 continue;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001463 numAlgosOffered++;
Alexandre Lision51140e12013-12-02 10:54:09 -05001464 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001465 // Lookup offered algos in configured algos. Prefer algorithms that appear first in Hello packet (offered).
Alexandre Lision51140e12013-12-02 10:54:09 -05001466 for (i = 0; i < numAlgosOffered; i++) {
1467 for (ii = 0; ii < numAlgosConf; ii++) {
1468 if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
1469 return algosConf[ii];
1470 }
1471 }
1472 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001473 // If we don't have a match - use the mandatory algorithm
Alexandre Lision51140e12013-12-02 10:54:09 -05001474 return &zrtpSasTypes.getByName(mandatorySasType);
1475}
1476
1477AlgorithmEnum* ZRtp::findBestAuthLen(ZrtpPacketHello *hello) {
1478
1479 int i;
1480 int ii;
1481 int numAlgosOffered;
1482 AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+2];
1483
1484 int numAlgosConf;
1485 AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+2];
1486
Alexandre Lision51140e12013-12-02 10:54:09 -05001487 int num = hello->getNumAuth();
1488 if (num == 0) {
1489 return &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
1490 }
1491
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001492 // Build list of configured Authentication tag length algorithm names.
Alexandre Lision51140e12013-12-02 10:54:09 -05001493 numAlgosConf = configureAlgos.getNumConfiguredAlgos(AuthLength);
1494 for (i = 0; i < numAlgosConf; i++) {
1495 algosConf[i] = &configureAlgos.getAlgoAt(AuthLength, i);
Alexandre Lision51140e12013-12-02 10:54:09 -05001496 }
1497
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001498 // Build list of offered known algos in Hello.
Alexandre Lision51140e12013-12-02 10:54:09 -05001499 for (numAlgosOffered = 0, i = 0; i < num; i++) {
1500 algosOffered[numAlgosOffered] = &zrtpAuthLengths.getByName((const char*)hello->getAuthLen(i));
1501 if (!algosOffered[numAlgosOffered]->isValid())
1502 continue;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001503 numAlgosOffered++;
Alexandre Lision51140e12013-12-02 10:54:09 -05001504 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001505
1506 // Lookup offered algos in configured algos. Prefer algorithms that appear first in Hello packet (offered).
Alexandre Lision51140e12013-12-02 10:54:09 -05001507 for (i = 0; i < numAlgosOffered; i++) {
1508 for (ii = 0; ii < numAlgosConf; ii++) {
1509 if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
1510 return algosConf[ii];
1511 }
1512 }
1513 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001514 // If we don't have a match - use the mandatory algorithm
Alexandre Lision51140e12013-12-02 10:54:09 -05001515 return &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
1516}
1517
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001518AlgorithmEnum* ZRtp::getStrongHashOffered(ZrtpPacketHello *hello) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001519
1520 int numHash = hello->getNumHashes();
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001521 for (int i = 0; i < numHash; i++) {
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001522 if (*(int32_t*)(hello->getHashType(i)) == *(int32_t*)s384) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001523 return &zrtpHashes.getByName((const char*)hello->getHashType(i));
1524 }
1525 }
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001526 return NULL;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001527}
1528
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001529AlgorithmEnum* ZRtp::getStrongCipherOffered(ZrtpPacketHello *hello) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001530
1531 int num = hello->getNumCiphers();
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001532 for (int i = 0; i < num; i++) {
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001533 if (*(int32_t*)(hello->getCipherType(i)) == *(int32_t*)aes3 ||
1534 *(int32_t*)(hello->getCipherType(i)) == *(int32_t*)two3) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001535 return &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));
1536 }
1537 }
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001538 return NULL;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001539}
1540
Alexandre Lision51140e12013-12-02 10:54:09 -05001541bool ZRtp::checkMultiStream(ZrtpPacketHello *hello) {
1542
1543 int i;
1544 int num = hello->getNumPubKeys();
1545
1546 // Multi Stream mode is mandatory, thus if nothing is offered then it is supported :-)
1547 if (num == 0) {
1548 return true;
1549 }
1550 for (i = 0; i < num; i++) {
1551 if (*(int32_t*)(hello->getPubKeyType(i)) == *(int32_t*)mult) {
1552 return true;
1553 }
1554 }
1555 return false;
1556}
1557
1558bool ZRtp::verifyH2(ZrtpPacketCommit *commit) {
1559 uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];
1560
1561 sha256(commit->getH2(), HASH_IMAGE_SIZE, tmpH3);
1562 if (memcmp(tmpH3, peerH3, HASH_IMAGE_SIZE) != 0) {
1563 return false;
1564 }
1565 return true;
1566}
1567
1568void ZRtp::computeHvi(ZrtpPacketDHPart* dh, ZrtpPacketHello *hello) {
1569
1570 unsigned char* data[3];
1571 unsigned int length[3];
1572 /*
1573 * populate the vector to compute the HVI hash according to the
1574 * ZRTP specification.
1575 */
1576 data[0] = (uint8_t*)dh->getHeaderBase();
1577 length[0] = dh->getLength() * ZRTP_WORD_SIZE;
1578
1579 data[1] = (uint8_t*)hello->getHeaderBase();
1580 length[1] = hello->getLength() * ZRTP_WORD_SIZE;
1581
1582 data[2] = NULL; // terminate data chunks
1583 hashListFunction(data, length, hvi);
1584 return;
1585}
1586
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001587void ZRtp:: computeSharedSecretSet(ZIDRecord *zidRec) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001588
1589 /*
1590 * Compute the Initiator's and Reponder's retained shared secret Ids.
1591 * Use negotiated HMAC.
1592 */
1593 uint8_t randBuf[RS_LENGTH];
1594 uint32_t macLen;
1595
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001596 detailInfo.secretsCached = 0;
1597 if (!zidRec->isRs1Valid()) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001598 randomZRTP(randBuf, RS_LENGTH);
1599 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs1IDi, &macLen);
1600 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), rs1IDr, &macLen);
1601 }
1602 else {
1603 rs1Valid = true;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001604 hmacFunction((unsigned char*)zidRec->getRs1(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs1IDi, &macLen);
1605 hmacFunction((unsigned char*)zidRec->getRs1(), RS_LENGTH, (unsigned char*)responder, strlen(responder), rs1IDr, &macLen);
1606 detailInfo.secretsCached = Rs1;
Alexandre Lision51140e12013-12-02 10:54:09 -05001607 }
1608
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001609 if (!zidRec->isRs2Valid()) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001610 randomZRTP(randBuf, RS_LENGTH);
1611 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs2IDi, &macLen);
1612 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), rs2IDr, &macLen);
1613 }
1614 else {
1615 rs2Valid = true;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001616 hmacFunction((unsigned char*)zidRec->getRs2(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs2IDi, &macLen);
1617 hmacFunction((unsigned char*)zidRec->getRs2(), RS_LENGTH, (unsigned char*)responder, strlen(responder), rs2IDr, &macLen);
1618 detailInfo.secretsCached |= Rs2;
Alexandre Lision51140e12013-12-02 10:54:09 -05001619 }
1620
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001621 /*
1622 * For the time being we don't support this type of shared secrect. Could be
1623 * easily done: somebody sets some data into our ZRtp object, check it here
1624 * and use it. Otherwise use the random data.
1625 */
1626 randomZRTP(randBuf, RS_LENGTH);
1627 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), auxSecretIDi, &macLen);
1628 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), auxSecretIDr, &macLen);
1629
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001630 if (!zidRec->isMITMKeyAvailable()) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001631 randomZRTP(randBuf, RS_LENGTH);
1632 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), pbxSecretIDi, &macLen);
1633 hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), pbxSecretIDr, &macLen);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001634
Alexandre Lision51140e12013-12-02 10:54:09 -05001635 }
1636 else {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001637 hmacFunction((unsigned char*)zidRec->getMiTMData(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), pbxSecretIDi, &macLen);
1638 hmacFunction((unsigned char*)zidRec->getMiTMData(), RS_LENGTH, (unsigned char*)responder, strlen(responder), pbxSecretIDr, &macLen);
1639 detailInfo.secretsCached |= Pbx;
1640 }
Alexandre Lision51140e12013-12-02 10:54:09 -05001641}
1642
1643/*
1644 * The DH packet for this function is DHPart1 and contains the Responder's
1645 * retained secret ids. Compare them with the expected secret ids (refer
1646 * to chapter 5.3 in the specification).
1647 * When using this method then we are in Initiator role.
1648 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001649void ZRtp::generateKeysInitiator(ZrtpPacketDHPart *dhPart, ZIDRecord *zidRec) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001650 const uint8_t* setD[3];
1651 int32_t rsFound = 0;
1652
1653 setD[0] = setD[1] = setD[2] = NULL;
1654
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001655 detailInfo.secretsMatchedDH = 0;
1656 if (memcmp(rs1IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs1IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0)
1657 detailInfo.secretsMatchedDH |= Rs1;
1658 if (memcmp(rs2IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs2IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0)
1659 detailInfo.secretsMatchedDH |= Rs2;
Alexandre Lision51140e12013-12-02 10:54:09 -05001660 /*
1661 * Select the real secrets into setD. The dhPart is DHpart1 message
1662 * received from responder. rs1IDr and rs2IDr are the expected ids using
1663 * the initator's cached retained secrets.
1664 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001665 // Check which RS we shall use for first place (s1)
1666 detailInfo.secretsMatched = 0;
Alexandre Lision51140e12013-12-02 10:54:09 -05001667 if (memcmp(rs1IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001668 setD[0] = zidRec->getRs1();
Alexandre Lision51140e12013-12-02 10:54:09 -05001669 rsFound = 0x1;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001670 detailInfo.secretsMatched = Rs1;
Alexandre Lision51140e12013-12-02 10:54:09 -05001671 }
1672 else if (memcmp(rs1IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001673 setD[0] = zidRec->getRs1();
Alexandre Lision51140e12013-12-02 10:54:09 -05001674 rsFound = 0x2;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001675 detailInfo.secretsMatched = Rs1;
Alexandre Lision51140e12013-12-02 10:54:09 -05001676 }
1677 else if (memcmp(rs2IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001678 setD[0] = zidRec->getRs2();
Alexandre Lision51140e12013-12-02 10:54:09 -05001679 rsFound = 0x4;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001680 detailInfo.secretsMatched = Rs2;
Alexandre Lision51140e12013-12-02 10:54:09 -05001681 }
1682 else if (memcmp(rs2IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001683 setD[0] = zidRec->getRs2();
Alexandre Lision51140e12013-12-02 10:54:09 -05001684 rsFound = 0x8;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001685 detailInfo.secretsMatched = Rs2;
Alexandre Lision51140e12013-12-02 10:54:09 -05001686 }
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001687 /* *** Not yet supported
Alexandre Lision51140e12013-12-02 10:54:09 -05001688 if (memcmp(auxSecretIDr, dhPart->getAuxSecretId(), 8) == 0) {
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001689 DEBUGOUT((fprintf(stdout, "%c: Match for aux secret found\n", zid[0])));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001690 setD[1] = auxSecret;
Alexandre Lision51140e12013-12-02 10:54:09 -05001691 }
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001692 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001693 // check if we have a matching PBX secret and place it third (s3)
1694 if (memcmp(pbxSecretIDr, dhPart->getPbxSecretId(), HMAC_SIZE) == 0) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001695 DEBUGOUT((fprintf(stdout, "%c: Match for Other_secret found\n", zid[0])));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001696 setD[2] = zidRec->getMiTMData();
1697 detailInfo.secretsMatched |= Pbx;
1698 detailInfo.secretsMatchedDH |= Pbx;
1699 // Flag to record that fact that we have a MitM key of the other peer.
1700 peerIsEnrolled = true;
Alexandre Lision51140e12013-12-02 10:54:09 -05001701 }
1702 // Check if some retained secrets found
1703 if (rsFound == 0) { // no RS matches found
1704 if (rs1Valid || rs2Valid) { // but valid RS records in cache
1705 sendInfo(Warning, WarningNoExpectedRSMatch);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001706 zidRec->resetSasVerified();
Alexandre Lision51140e12013-12-02 10:54:09 -05001707 }
1708 else { // No valid RS record in cache
1709 sendInfo(Warning, WarningNoRSMatch);
1710 }
1711 }
1712 else { // at least one RS matches
1713 sendInfo(Info, InfoRSMatchFound);
1714 }
1715 /*
1716 * Ready to generate s0 here.
1717 * The formular to compute S0 (Refer to ZRTP specification 5.4.4):
1718 *
1719 s0 = hash( counter | DHResult | "ZRTP-HMAC-KDF" | ZIDi | ZIDr | \
1720 total_hash | len(s1) | s1 | len(s2) | s2 | len(s3) | s3)
1721 *
1722 * Note: in this function we are Initiator, thus ZIDi is our zid
1723 * (zid), ZIDr is the peer's zid (peerZid).
1724 */
1725
1726 /*
1727 * These arrays hold the pointers and lengths of the data that must be
1728 * hashed to create S0. According to the formula the max number of
1729 * elements to hash is 12, add one for the terminating "NULL"
1730 */
1731 unsigned char* data[13];
1732 unsigned int length[13];
1733 uint32_t pos = 0; // index into the array
1734
1735 // we need a number of length data items, so define them here
1736 uint32_t counter, sLen[3];
1737
1738 //Very first element is a fixed counter, big endian
1739 counter = 1;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001740 counter = zrtpHtonl(counter);
Alexandre Lision51140e12013-12-02 10:54:09 -05001741 data[pos] = (unsigned char*)&counter;
1742 length[pos++] = sizeof(uint32_t);
1743
1744 // Next is the DH result itself
1745 data[pos] = DHss;
1746 length[pos++] = dhContext->getDhSize();
1747
1748 // Next the fixed string "ZRTP-HMAC-KDF"
1749 data[pos] = (unsigned char*)KDFString;
1750 length[pos++] = strlen(KDFString);
1751
1752 // Next is Initiator's id (ZIDi), in this case as Initiator
1753 // it is zid
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001754 data[pos] = ownZid;
Alexandre Lision51140e12013-12-02 10:54:09 -05001755 length[pos++] = ZID_SIZE;
1756
1757 // Next is Responder's id (ZIDr), in this case our peer's id
1758 data[pos] = peerZid;
1759 length[pos++] = ZID_SIZE;
1760
1761 // Next ist total hash (messageHash) itself
1762 data[pos] = messageHash;
1763 length[pos++] = hashLength;
1764
1765 /*
1766 * For each matching shared secret hash the length of
1767 * the shared secret as 32 bit big-endian number followd by the
1768 * shared secret itself. The length of a shared seceret is
1769 * currently fixed to RS_LENGTH. If a shared
1770 * secret is not used _only_ its length is hased as zero
1771 * length. NOTE: if implementing auxSecret and/or pbxSecret -> check
1772 * this length stuff again.
1773 */
1774 int secretHashLen = RS_LENGTH;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001775 secretHashLen = zrtpHtonl(secretHashLen); // prepare 32 bit big-endian number
Alexandre Lision51140e12013-12-02 10:54:09 -05001776
1777 for (int32_t i = 0; i < 3; i++) {
1778 if (setD[i] != NULL) { // a matching secret, set length, then secret
1779 sLen[i] = secretHashLen;
1780 data[pos] = (unsigned char*)&sLen[i];
1781 length[pos++] = sizeof(uint32_t);
1782 data[pos] = (unsigned char*)setD[i];
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001783 length[pos++] = RS_LENGTH;
Alexandre Lision51140e12013-12-02 10:54:09 -05001784 }
1785 else { // no machting secret, set length 0, skip secret
1786 sLen[i] = 0;
1787 data[pos] = (unsigned char*)&sLen[i];
1788 length[pos++] = sizeof(uint32_t);
1789 }
1790 }
1791
1792 data[pos] = NULL;
1793 hashListFunction(data, length, s0);
1794// hexdump("S0 I", s0, hashLength);
1795
1796 memset(DHss, 0, dhContext->getDhSize());
1797 delete[] DHss;
1798 DHss = NULL;
1799
1800 computeSRTPKeys();
1801 memset(s0, 0, MAX_DIGEST_LENGTH);
1802}
1803/*
1804 * The DH packet for this function is DHPart2 and contains the Initiator's
1805 * retained secret ids. Compare them with the expected secret ids (refer
1806 * to chapter 5.3.1 in the specification).
1807 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001808void ZRtp::generateKeysResponder(ZrtpPacketDHPart *dhPart, ZIDRecord *zidRec) {
Alexandre Lision51140e12013-12-02 10:54:09 -05001809 const uint8_t* setD[3];
1810 int32_t rsFound = 0;
1811
1812 setD[0] = setD[1] = setD[2] = NULL;
1813
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001814 detailInfo.secretsMatchedDH = 0;
1815 if (memcmp(rs1IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs1IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0)
1816 detailInfo.secretsMatchedDH |= Rs1;
1817 if (memcmp(rs2IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs2IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0)
1818 detailInfo.secretsMatchedDH |= Rs2;
1819
Alexandre Lision51140e12013-12-02 10:54:09 -05001820 /*
1821 * Select the real secrets into setD
1822 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001823 // Check which RS we shall use for first place (s1)
1824 detailInfo.secretsMatched = 0;
Alexandre Lision51140e12013-12-02 10:54:09 -05001825 if (memcmp(rs1IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001826 setD[0] = zidRec->getRs1();
Alexandre Lision51140e12013-12-02 10:54:09 -05001827 rsFound = 0x1;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001828 detailInfo.secretsMatched = Rs1;
Alexandre Lision51140e12013-12-02 10:54:09 -05001829 }
1830 else if (memcmp(rs1IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001831 setD[0] = zidRec->getRs1();
Alexandre Lision51140e12013-12-02 10:54:09 -05001832 rsFound = 0x2;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001833 detailInfo.secretsMatched = Rs1;
Alexandre Lision51140e12013-12-02 10:54:09 -05001834 }
1835 else if (memcmp(rs2IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001836 setD[0] = zidRec->getRs2();
1837 rsFound |= 0x4;
1838 detailInfo.secretsMatched = Rs2;
1839 }
1840 else if (memcmp(rs2IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
1841 setD[0] = zidRec->getRs2();
Alexandre Lision51140e12013-12-02 10:54:09 -05001842 rsFound |= 0x8;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001843 detailInfo.secretsMatched = Rs2;
Alexandre Lision51140e12013-12-02 10:54:09 -05001844 }
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001845 /* ***** not yet supported
1846 if (memcmp(auxSecretIDi, dhPart->getauxSecretId(), 8) == 0) {
1847 DEBUGOUT((fprintf(stdout, "%c: Match for aux secret found\n", ownZidzid[0])));
1848 setD[1] = ;
Alexandre Lision51140e12013-12-02 10:54:09 -05001849 }
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001850 */
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001851
Alexandre Lision51140e12013-12-02 10:54:09 -05001852 if (memcmp(pbxSecretIDi, dhPart->getPbxSecretId(), 8) == 0) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001853 DEBUGOUT((fprintf(stdout, "%c: Match for PBX secret found\n", ownZid[0])));
1854 setD[2] = zidRec->getMiTMData();
1855 detailInfo.secretsMatched |= Pbx;
1856 detailInfo.secretsMatchedDH |= Pbx;
1857 peerIsEnrolled = true;
Alexandre Lision51140e12013-12-02 10:54:09 -05001858 }
1859 // Check if some retained secrets found
1860 if (rsFound == 0) { // no RS matches found
1861 if (rs1Valid || rs2Valid) { // but valid RS records in cache
1862 sendInfo(Warning, WarningNoExpectedRSMatch);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001863 zidRec->resetSasVerified();
Alexandre Lision51140e12013-12-02 10:54:09 -05001864 }
1865 else { // No valid RS record in cache
1866 sendInfo(Warning, WarningNoRSMatch);
1867 }
1868 }
1869 else { // at least one RS matches
1870 sendInfo(Info, InfoRSMatchFound);
1871 }
1872
1873 /*
1874 * ready to generate s0 here.
1875 * The formular to compute S0 (Refer to ZRTP specification 5.4.4):
1876 *
1877 s0 = hash( counter | DHResult | "ZRTP-HMAC-KDF" | ZIDi | ZIDr | \
1878 total_hash | len(s1) | s1 | len(s2) | s2 | len(s3) | s3)
1879 *
1880 * Note: in this function we are Responder, thus ZIDi is the peer's zid
1881 * (peerZid), ZIDr is our zid.
1882 */
1883
1884 /*
1885 * These arrays hold the pointers and lengths of the data that must be
1886 * hashed to create S0. According to the formula the max number of
1887 * elements to hash is 12, add one for the terminating "NULL"
1888 */
1889 unsigned char* data[13];
1890 unsigned int length[13];
1891 uint32_t pos = 0; // index into the array
1892
1893
1894 // we need a number of length data items, so define them here
1895 uint32_t counter, sLen[3];
1896
1897 //Very first element is a fixed counter, big endian
1898 counter = 1;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001899 counter = zrtpHtonl(counter);
Alexandre Lision51140e12013-12-02 10:54:09 -05001900 data[pos] = (unsigned char*)&counter;
1901 length[pos++] = sizeof(uint32_t);
1902
1903 // Next is the DH result itself
1904 data[pos] = DHss;
1905 length[pos++] = dhContext->getDhSize();
1906
1907 // Next the fixed string "ZRTP-HMAC-KDF"
1908 data[pos] = (unsigned char*)KDFString;
1909 length[pos++] = strlen(KDFString);
1910
1911 // Next is Initiator's id (ZIDi), in this case as Responder
1912 // it is peerZid
1913 data[pos] = peerZid;
1914 length[pos++] = ZID_SIZE;
1915
1916 // Next is Responder's id (ZIDr), in this case our own zid
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001917 data[pos] = ownZid;
Alexandre Lision51140e12013-12-02 10:54:09 -05001918 length[pos++] = ZID_SIZE;
1919
1920 // Next ist total hash (messageHash) itself
1921 data[pos] = messageHash;
1922 length[pos++] = hashLength;
1923
1924 /*
1925 * For each matching shared secret hash the length of
1926 * the shared secret as 32 bit big-endian number followd by the
1927 * shared secret itself. The length of a shared seceret is
1928 * currently fixed to SHA256_DIGEST_LENGTH. If a shared
1929 * secret is not used _only_ its length is hased as zero
1930 * length. NOTE: if implementing auxSecret and/or pbxSecret -> check
1931 * this length stuff again.
1932 */
1933 int secretHashLen = RS_LENGTH;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001934 secretHashLen = zrtpHtonl(secretHashLen); // prepare 32 bit big-endian number
Alexandre Lision51140e12013-12-02 10:54:09 -05001935
1936 for (int32_t i = 0; i < 3; i++) {
1937 if (setD[i] != NULL) { // a matching secret, set length, then secret
1938 sLen[i] = secretHashLen;
1939 data[pos] = (unsigned char*)&sLen[i];
1940 length[pos++] = sizeof(uint32_t);
1941 data[pos] = (unsigned char*)setD[i];
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001942 length[pos++] = RS_LENGTH;
Alexandre Lision51140e12013-12-02 10:54:09 -05001943 }
1944 else { // no machting secret, set length 0, skip secret
1945 sLen[i] = 0;
1946 data[pos] = (unsigned char*)&sLen[i];
1947 length[pos++] = sizeof(uint32_t);
1948 }
1949 }
1950
1951 data[pos] = NULL;
1952 hashListFunction(data, length, s0);
1953// hexdump("S0 R", s0, hashLength);
1954
1955 memset(DHss, 0, dhContext->getDhSize());
1956 delete[] DHss;
1957 DHss = NULL;
1958
1959 computeSRTPKeys();
1960 memset(s0, 0, MAX_DIGEST_LENGTH);
1961}
1962
1963
1964void ZRtp::KDF(uint8_t* key, uint32_t keyLength, uint8_t* label, int32_t labelLength,
1965 uint8_t* context, int32_t contextLength, int32_t L, uint8_t* output) {
1966
1967 unsigned char* data[6];
1968 uint32_t length[6];
1969 uint32_t pos = 0; // index into the array
1970 uint32_t maclen = 0;
1971
1972 // Very first element is a fixed counter, big endian
1973 uint32_t counter = 1;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001974 counter = zrtpHtonl(counter);
Alexandre Lision51140e12013-12-02 10:54:09 -05001975 data[pos] = (unsigned char*)&counter;
1976 length[pos++] = sizeof(uint32_t);
1977
1978 // Next element is the label, null terminated, labelLength includes null byte.
1979 data[pos] = label;
1980 length[pos++] = labelLength;
1981
1982 // Next is the KDF context
1983 data[pos] = context;
1984 length[pos++] = contextLength;
1985
1986 // last element is HMAC length in bits, big endian
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001987 uint32_t len = zrtpHtonl(L);
Alexandre Lision51140e12013-12-02 10:54:09 -05001988 data[pos] = (unsigned char*)&len;
1989 length[pos++] = sizeof(uint32_t);
1990
1991 data[pos] = NULL;
1992
1993 // Use negotiated hash.
1994 hmacListFunction(key, keyLength, data, length, output, &maclen);
1995}
1996
1997// Compute the Multi Stream mode s0
1998void ZRtp::generateKeysMultiStream() {
1999
2000 // allocate the maximum size, compute real size to use
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002001 uint8_t KDFcontext[sizeof(peerZid)+sizeof(ownZid)+sizeof(messageHash)];
2002 int32_t kdfSize = sizeof(peerZid)+sizeof(ownZid)+hashLength;
Alexandre Lision51140e12013-12-02 10:54:09 -05002003
2004 if (myRole == Responder) {
2005 memcpy(KDFcontext, peerZid, sizeof(peerZid));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002006 memcpy(KDFcontext+sizeof(peerZid), ownZid, sizeof(ownZid));
Alexandre Lision51140e12013-12-02 10:54:09 -05002007 }
2008 else {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002009 memcpy(KDFcontext, ownZid, sizeof(ownZid));
2010 memcpy(KDFcontext+sizeof(ownZid), peerZid, sizeof(peerZid));
Alexandre Lision51140e12013-12-02 10:54:09 -05002011 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002012 memcpy(KDFcontext+sizeof(ownZid)+sizeof(peerZid), messageHash, hashLength);
Alexandre Lision51140e12013-12-02 10:54:09 -05002013
2014 KDF(zrtpSession, hashLength, (unsigned char*)zrtpMsk, strlen(zrtpMsk)+1, KDFcontext, kdfSize, hashLength*8, s0);
2015
2016 memset(KDFcontext, 0, sizeof(KDFcontext));
2017
2018 computeSRTPKeys();
2019}
2020
2021void ZRtp::computePBXSecret() {
2022 // Construct the KDF context as per ZRTP specification chap 7.3.1:
2023 // ZIDi || ZIDr
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002024 uint8_t KDFcontext[sizeof(peerZid)+sizeof(ownZid)];
2025 int32_t kdfSize = sizeof(peerZid)+sizeof(ownZid);
Alexandre Lision51140e12013-12-02 10:54:09 -05002026
2027 if (myRole == Responder) {
2028 memcpy(KDFcontext, peerZid, sizeof(peerZid));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002029 memcpy(KDFcontext+sizeof(peerZid), ownZid, sizeof(ownZid));
Alexandre Lision51140e12013-12-02 10:54:09 -05002030 }
2031 else {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002032 memcpy(KDFcontext, ownZid, sizeof(ownZid));
2033 memcpy(KDFcontext+sizeof(ownZid), peerZid, sizeof(peerZid));
Alexandre Lision51140e12013-12-02 10:54:09 -05002034 }
2035
2036 KDF(zrtpSession, hashLength, (unsigned char*)zrtpTrustedMitm, strlen(zrtpTrustedMitm)+1, KDFcontext,
2037 kdfSize, SHA256_DIGEST_LENGTH * 8, pbxSecretTmpBuffer);
2038
2039 pbxSecretTmp = pbxSecretTmpBuffer; // set pointer to buffer, signal PBX secret was computed
2040}
2041
2042
2043void ZRtp::computeSRTPKeys() {
2044
2045 // allocate the maximum size, compute real size to use
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002046 uint8_t KDFcontext[sizeof(peerZid)+sizeof(ownZid)+sizeof(messageHash)];
2047 int32_t kdfSize = sizeof(peerZid)+sizeof(ownZid)+hashLength;
Alexandre Lision51140e12013-12-02 10:54:09 -05002048
2049 int32_t keyLen = cipher->getKeylen() * 8;
2050
2051 if (myRole == Responder) {
2052 memcpy(KDFcontext, peerZid, sizeof(peerZid));
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002053 memcpy(KDFcontext+sizeof(peerZid), ownZid, sizeof(ownZid));
Alexandre Lision51140e12013-12-02 10:54:09 -05002054 }
2055 else {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002056 memcpy(KDFcontext, ownZid, sizeof(ownZid));
2057 memcpy(KDFcontext+sizeof(ownZid), peerZid, sizeof(peerZid));
Alexandre Lision51140e12013-12-02 10:54:09 -05002058 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002059 memcpy(KDFcontext+sizeof(ownZid)+sizeof(peerZid), messageHash, hashLength);
Alexandre Lision51140e12013-12-02 10:54:09 -05002060
2061 // Inititiator key and salt
2062 KDF(s0, hashLength, (unsigned char*)iniMasterKey, strlen(iniMasterKey)+1, KDFcontext, kdfSize, keyLen, srtpKeyI);
2063 KDF(s0, hashLength, (unsigned char*)iniMasterSalt, strlen(iniMasterSalt)+1, KDFcontext, kdfSize, 112, srtpSaltI);
2064
2065 // Responder key and salt
2066 KDF(s0, hashLength, (unsigned char*)respMasterKey, strlen(respMasterKey)+1, KDFcontext, kdfSize, keyLen, srtpKeyR);
2067 KDF(s0, hashLength, (unsigned char*)respMasterSalt, strlen(respMasterSalt)+1, KDFcontext, kdfSize, 112, srtpSaltR);
2068
2069 // The HMAC keys for GoClear
2070 KDF(s0, hashLength, (unsigned char*)iniHmacKey, strlen(iniHmacKey)+1, KDFcontext, kdfSize, hashLength*8, hmacKeyI);
Alexandre Lision51140e12013-12-02 10:54:09 -05002071 KDF(s0, hashLength, (unsigned char*)respHmacKey, strlen(respHmacKey)+1, KDFcontext, kdfSize, hashLength*8, hmacKeyR);
2072
2073 // The keys for Confirm messages
2074 KDF(s0, hashLength, (unsigned char*)iniZrtpKey, strlen(iniZrtpKey)+1, KDFcontext, kdfSize, keyLen, zrtpKeyI);
2075 KDF(s0, hashLength, (unsigned char*)respZrtpKey, strlen(respZrtpKey)+1, KDFcontext, kdfSize, keyLen, zrtpKeyR);
2076
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002077 detailInfo.pubKey = detailInfo.sasType = NULL;
Alexandre Lision51140e12013-12-02 10:54:09 -05002078 if (!multiStream) {
2079 // Compute the new Retained Secret
2080 KDF(s0, hashLength, (unsigned char*)retainedSec, strlen(retainedSec)+1, KDFcontext, kdfSize, SHA256_DIGEST_LENGTH*8, newRs1);
2081
2082 // Compute the ZRTP Session Key
2083 KDF(s0, hashLength, (unsigned char*)zrtpSessionKey, strlen(zrtpSessionKey)+1, KDFcontext, kdfSize, hashLength*8, zrtpSession);
2084
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002085 // perform generation according to chapter 5.5 and 8.
Alexandre Lision51140e12013-12-02 10:54:09 -05002086 // we don't need a speciai sasValue filed. sasValue are the first
2087 // (leftmost) 32 bits (4 bytes) of sasHash
2088 uint8_t sasBytes[4];
2089 KDF(s0, hashLength, (unsigned char*)sasString, strlen(sasString)+1, KDFcontext, kdfSize, SHA256_DIGEST_LENGTH*8, sasHash);
2090
2091 // according to chapter 8 only the leftmost 20 bits of sasValue (aka
2092 // sasHash) are used to create the character SAS string of type SAS
2093 // base 32 (5 bits per character)
2094 sasBytes[0] = sasHash[0];
2095 sasBytes[1] = sasHash[1];
2096 sasBytes[2] = sasHash[2] & 0xf0;
2097 sasBytes[3] = 0;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002098 if (*(int32_t*)b32 == *(int32_t*)(sasType->getName())) {
2099 SAS = Base32(sasBytes, 20).getEncoded();
2100 }
2101 else {
2102 SAS.assign(sas256WordsEven[sasBytes[0]]).append(":").append(sas256WordsOdd[sasBytes[1]]);
2103 }
2104
Alexandre Lision51140e12013-12-02 10:54:09 -05002105 if (signSasSeen)
2106 callback->signSAS(sasHash);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002107
2108 detailInfo.pubKey = pubKey->getReadable();
2109 detailInfo.sasType = sasType->getReadable();
Alexandre Lision51140e12013-12-02 10:54:09 -05002110 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002111 // set algorithm names into detailInfo structure
2112 detailInfo.authLength = authLength->getReadable();
2113 detailInfo.cipher = cipher->getReadable();
2114 detailInfo.hash = hash->getReadable();
2115
Alexandre Lision51140e12013-12-02 10:54:09 -05002116 memset(KDFcontext, 0, sizeof(KDFcontext));
2117}
2118
2119bool ZRtp::srtpSecretsReady(EnableSecurity part) {
2120
2121 SrtpSecret_t sec;
2122
2123 sec.symEncAlgorithm = cipher->getAlgoId();
2124
2125 sec.keyInitiator = srtpKeyI;
2126 sec.initKeyLen = cipher->getKeylen() * 8;
2127 sec.saltInitiator = srtpSaltI;
2128 sec.initSaltLen = 112;
2129
2130 sec.keyResponder = srtpKeyR;
2131 sec.respKeyLen = cipher->getKeylen() * 8;
2132 sec.saltResponder = srtpSaltR;
2133 sec.respSaltLen = 112;
2134
2135 sec.authAlgorithm = authLength->getAlgoId();
2136 sec.srtpAuthTagLen = authLength->getKeylen();
2137
2138 sec.sas = SAS;
2139 sec.role = myRole;
2140
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002141 bool rc = callback->srtpSecretsReady(&sec, part);
2142
2143 // The call state engine calls ForSender always after ForReceiver.
2144 if (part == ForSender) {
2145 std::string cs(cipher->getReadable());
2146 if (!multiStream) {
2147 cs.append("/").append(pubKey->getName());
2148 if (mitmSeen)
2149 cs.append("/EndAtMitM");
2150 callback->srtpSecretsOn(cs, SAS, zidRec->isSasVerified());
2151 }
2152 else {
2153 std::string cs1("");
2154 if (mitmSeen)
2155 cs.append("/EndAtMitM");
2156 callback->srtpSecretsOn(cs, cs1, true);
2157 }
2158 }
2159 return rc;
Alexandre Lision51140e12013-12-02 10:54:09 -05002160}
2161
2162
2163void ZRtp::setNegotiatedHash(AlgorithmEnum* hash) {
2164 switch (zrtpHashes.getOrdinal(*hash)) {
2165 case 0:
2166 hashLength = SHA256_DIGEST_LENGTH;
2167 hashFunction = sha256;
2168 hashListFunction = sha256;
2169
2170 hmacFunction = hmac_sha256;
2171 hmacListFunction = hmac_sha256;
2172
2173 createHashCtx = createSha256Context;
2174 closeHashCtx = closeSha256Context;
2175 hashCtxFunction = sha256Ctx;
2176 hashCtxListFunction = sha256Ctx;
2177 break;
2178
2179 case 1:
2180 hashLength = SHA384_DIGEST_LENGTH;
2181 hashFunction = sha384;
2182 hashListFunction = sha384;
2183
2184 hmacFunction = hmac_sha384;
2185 hmacListFunction = hmac_sha384;
2186
2187 createHashCtx = createSha384Context;
2188 closeHashCtx = closeSha384Context;
2189 hashCtxFunction = sha384Ctx;
2190 hashCtxListFunction = sha384Ctx;
2191 break;
2192 }
2193}
2194
2195
2196void ZRtp::srtpSecretsOff(EnableSecurity part) {
2197 callback->srtpSecretsOff(part);
2198}
2199
2200void ZRtp::SASVerified() {
2201 if (paranoidMode)
2202 return;
2203
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002204 zidRec->setSasVerified();
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002205 getZidCacheInstance()->saveRecord(zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -05002206}
2207
2208void ZRtp::resetSASVerified() {
Alexandre Lision51140e12013-12-02 10:54:09 -05002209
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002210 zidRec->resetSasVerified();
2211 getZidCacheInstance()->saveRecord(zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -05002212}
2213
2214
2215void ZRtp::sendInfo(GnuZrtpCodes::MessageSeverity severity, int32_t subCode) {
2216
2217 // We've reached secure state: overwrite the SRTP master key and master salt.
2218 if (severity == Info && subCode == InfoSecureStateOn) {
2219 memset(srtpKeyI, 0, cipher->getKeylen());
2220 memset(srtpSaltI, 0, 112/8);
2221 memset(srtpKeyR, 0, cipher->getKeylen());
2222 memset(srtpSaltR, 0, 112/8);
2223 }
2224 callback->sendInfo(severity, subCode);
2225}
2226
2227
2228void ZRtp::zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity severity, int32_t subCode) {
2229 callback->zrtpNegotiationFailed(severity, subCode);
2230}
2231
2232void ZRtp::zrtpNotSuppOther() {
2233 callback->zrtpNotSuppOther();
2234}
2235
2236void ZRtp::synchEnter() {
2237 callback->synchEnter();
2238}
2239
2240void ZRtp::synchLeave() {
2241 callback->synchLeave();
2242}
2243
2244int32_t ZRtp::sendPacketZRTP(ZrtpPacketBase *packet) {
2245 return ((packet == NULL) ? 0 :
2246 callback->sendDataZRTP(packet->getHeaderBase(), (packet->getLength() * 4) + 4));
2247}
2248
2249int32_t ZRtp::activateTimer(int32_t tm) {
2250 return (callback->activateTimer(tm));
2251}
2252
2253int32_t ZRtp::cancelTimer() {
2254 return (callback->cancelTimer());
2255}
2256
2257void ZRtp::setAuxSecret(uint8_t* data, int32_t length) {
2258 if (length > 0) {
2259 auxSecret = new uint8_t[length];
2260 auxSecretLength = length;
2261 memcpy(auxSecret, data, length);
2262 }
2263}
2264
Alexandre Lisionddd731e2014-01-31 11:50:08 -05002265void ZRtp::setClientId(std::string id) {
2266 if (id.size() < CLIENT_ID_SIZE) {
2267 unsigned char tmp[CLIENT_ID_SIZE +1] = {' '};
2268 memcpy(tmp, id.c_str(), id.size());
2269 tmp[CLIENT_ID_SIZE] = 0;
2270 zrtpHello.setClientId(tmp);
2271 } else {
2272 zrtpHello.setClientId((unsigned char*)id.c_str());
2273 }
Alexandre Lision51140e12013-12-02 10:54:09 -05002274
Alexandre Lisionddd731e2014-01-31 11:50:08 -05002275 int32_t len = zrtpHello.getLength() * ZRTP_WORD_SIZE;
Alexandre Lision51140e12013-12-02 10:54:09 -05002276
Alexandre Lisionddd731e2014-01-31 11:50:08 -05002277 // Hello packet is ready now, compute its HMAC
Alexandre Lision51140e12013-12-02 10:54:09 -05002278 // (excluding the HMAC field (2*ZTP_WORD_SIZE)) and store in Hello
2279 // use the implicit hash function
2280 uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];
2281 uint32_t macLen;
Alexandre Lisionddd731e2014-01-31 11:50:08 -05002282 hmacFunctionImpl(H2, HASH_IMAGE_SIZE, (uint8_t*)zrtpHello.getHeaderBase(), len-(2*ZRTP_WORD_SIZE), hmac, &macLen);
2283 zrtpHello.setHMAC(hmac);
Alexandre Lision51140e12013-12-02 10:54:09 -05002284
2285 // calculate hash over the final Hello packet, refer to chap 9.1 how to
2286 // use this hash in SIP/SDP.
Alexandre Lisionddd731e2014-01-31 11:50:08 -05002287 hashFunctionImpl((uint8_t*)zrtpHello.getHeaderBase(), len, helloHash);
Alexandre Lision51140e12013-12-02 10:54:09 -05002288}
2289
2290void ZRtp::storeMsgTemp(ZrtpPacketBase* pkt) {
Alexandre Lisionddd731e2014-01-31 11:50:08 -05002291 int32_t length = pkt->getLength() * ZRTP_WORD_SIZE;
Alexandre Lision51140e12013-12-02 10:54:09 -05002292 memset(tempMsgBuffer, 0, sizeof(tempMsgBuffer));
2293 memcpy(tempMsgBuffer, (uint8_t*)pkt->getHeaderBase(), length);
2294 lengthOfMsgData = length;
2295}
2296
2297bool ZRtp::checkMsgHmac(uint8_t* key) {
2298 uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];
2299 uint32_t macLen;
2300 int32_t len = lengthOfMsgData-(HMAC_SIZE); // compute HMAC, but exlude the stored HMAC :-)
2301
2302 // Use the implicit hash function
2303 hmacFunctionImpl(key, HASH_IMAGE_SIZE, tempMsgBuffer, len, hmac, &macLen);
2304 return (memcmp(hmac, tempMsgBuffer+len, (HMAC_SIZE)) == 0 ? true : false);
2305}
2306
Alexandre Lisionddd731e2014-01-31 11:50:08 -05002307std::string ZRtp::getHelloHash() {
Alexandre Lision51140e12013-12-02 10:54:09 -05002308 std::ostringstream stm;
2309
Alexandre Lisionddd731e2014-01-31 11:50:08 -05002310 uint8_t* hp = helloHash;
Alexandre Lision51140e12013-12-02 10:54:09 -05002311
Alexandre Lisionddd731e2014-01-31 11:50:08 -05002312 stm << zrtpVersion;
Alexandre Lision51140e12013-12-02 10:54:09 -05002313 stm << " ";
2314 stm.fill('0');
2315 stm << hex;
2316 for (int i = 0; i < hashLengthImpl; i++) {
2317 stm.width(2);
2318 stm << static_cast<uint32_t>(*hp++);
2319 }
2320 return stm.str();
2321}
2322
2323std::string ZRtp::getPeerHelloHash() {
2324 std::ostringstream stm;
2325
2326 if (peerHelloVersion[0] == 0)
2327 return std::string();
2328
2329 uint8_t* hp = peerHelloHash;
2330
2331 stm << peerHelloVersion;
2332 stm << " ";
2333 stm.fill('0');
2334 stm << hex;
2335 for (int i = 0; i < hashLengthImpl; i++) {
2336 stm.width(2);
2337 stm << static_cast<uint32_t>(*hp++);
2338 }
2339 return stm.str();
2340}
2341
2342std::string ZRtp::getMultiStrParams() {
2343
2344 // the string will hold binary data - it's opaque to the application
2345 std::string str("");
2346 char tmp[MAX_DIGEST_LENGTH + 1 + 1 + 1]; // hash length + cipher + authLength + hash
2347
2348 if (inState(SecureState) && !multiStream) {
2349 // construct array that holds zrtpSession, cipher type, auth-length, and hash type
2350 tmp[0] = zrtpHashes.getOrdinal(*hash);
2351 tmp[1] = zrtpAuthLengths.getOrdinal(*authLength);
2352 tmp[2] = zrtpSymCiphers.getOrdinal(*cipher);
2353 memcpy(tmp+3, zrtpSession, hashLength);
2354 str.assign(tmp, hashLength + 1 + 1 + 1); // set chars (bytes) to the string
2355 }
2356 return str;
2357}
2358
2359void ZRtp::setMultiStrParams(std::string parameters) {
2360
2361 char tmp[MAX_DIGEST_LENGTH + 1 + 1 + 1]; // max. hash length + cipher + authLength + hash
2362
2363 // First get negotiated hash from parameters, set algorithms and length
2364 int i = parameters.at(0) & 0xff;
2365 hash = &zrtpHashes.getByOrdinal(i);
2366 setNegotiatedHash(hash); // sets hashlength
2367
2368 // use string.copy(buffer, num, start=0) to retrieve chars (bytes) from the string
2369 parameters.copy(tmp, hashLength + 1 + 1 + 1, 0);
2370
2371 i = tmp[1] & 0xff;
2372 authLength = &zrtpAuthLengths.getByOrdinal(i);
2373 i = tmp[2] & 0xff;
2374 cipher = &zrtpSymCiphers.getByOrdinal(i);
2375 memcpy(zrtpSession, tmp+3, hashLength);
2376
2377 // after setting zrtpSession, cipher, and auth-length set multi-stream to true
2378 multiStream = true;
2379 stateEngine->setMultiStream(true);
2380}
2381
2382bool ZRtp::isMultiStream() {
2383 return multiStream;
2384}
2385
2386bool ZRtp::isMultiStreamAvailable() {
2387 return multiStreamAvailable;
2388}
2389
2390void ZRtp::acceptEnrollment(bool accepted) {
2391 if (!accepted) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002392 zidRec->resetMITMKeyAvailable();
Alexandre Lision51140e12013-12-02 10:54:09 -05002393 callback->zrtpInformEnrollment(EnrollmentCanceled);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002394 getZidCacheInstance()->saveRecord(zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -05002395 return;
2396 }
Alexandre Lision51140e12013-12-02 10:54:09 -05002397 if (pbxSecretTmp != NULL) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002398 zidRec->setMiTMData(pbxSecretTmp);
2399 getZidCacheInstance()->saveRecord(zidRec);
Alexandre Lision51140e12013-12-02 10:54:09 -05002400 callback->zrtpInformEnrollment(EnrollmentOk);
2401 }
2402 else {
2403 callback->zrtpInformEnrollment(EnrollmentFailed);
Alexandre Lision51140e12013-12-02 10:54:09 -05002404 }
Alexandre Lision51140e12013-12-02 10:54:09 -05002405 return;
2406}
2407
2408bool ZRtp::setSignatureData(uint8_t* data, int32_t length) {
2409 if ((length % 4) != 0)
2410 return false;
2411
2412 ZrtpPacketConfirm* cfrm = (myRole == Responder) ? &zrtpConfirm1 : &zrtpConfirm2;
2413 cfrm->setSignatureLength(length / 4);
2414 return cfrm->setSignatureData(data, length);
2415}
2416
2417const uint8_t* ZRtp::getSignatureData() {
2418 return signatureData;
2419}
2420
2421int32_t ZRtp::getSignatureLength() {
2422 return signatureLength * ZRTP_WORD_SIZE;
2423}
2424
2425void ZRtp::conf2AckSecure() {
2426 Event_t ev;
2427
2428 ev.type = ZrtpPacket;
Alexandre Lisionddd731e2014-01-31 11:50:08 -05002429 ev.packet = (uint8_t*)&zrtpConf2Ack;
Alexandre Lision51140e12013-12-02 10:54:09 -05002430
2431 if (stateEngine != NULL) {
2432 stateEngine->processEvent(&ev);
2433 }
2434}
2435
2436int32_t ZRtp::compareCommit(ZrtpPacketCommit *commit) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002437 // TODO: enhance to compare according to rules defined in chapter 4.2,
2438 // but we don't support Preshared.
Alexandre Lision51140e12013-12-02 10:54:09 -05002439 int32_t len = 0;
2440 len = !multiStream ? HVI_SIZE : (4 * ZRTP_WORD_SIZE);
2441 return (memcmp(hvi, commit->getHvi(), len));
2442}
2443
2444bool ZRtp::isEnrollmentMode() {
2445 return enrollmentMode;
2446}
2447
2448void ZRtp::setEnrollmentMode(bool enrollmentMode) {
2449 this->enrollmentMode = enrollmentMode;
2450}
2451
2452bool ZRtp::isPeerEnrolled() {
2453 return peerIsEnrolled;
2454}
2455
2456bool ZRtp::sendSASRelayPacket(uint8_t* sh, std::string render) {
2457
2458 uint8_t confMac[MAX_DIGEST_LENGTH];
2459 uint32_t macLen;
2460 uint8_t* hkey, *ekey;
2461
2462 // If we are responder then the PBX used it's Initiator keys
2463 if (myRole == Responder) {
2464 hkey = hmacKeyR;
2465 ekey = zrtpKeyR;
2466 // TODO: check signature length in zrtpConfirm1 and if not zero copy Signature data
2467 }
2468 else {
2469 hkey = hmacKeyI;
2470 ekey = zrtpKeyI;
2471 // TODO: check signature length in zrtpConfirm2 and if not zero copy Signature data
2472 }
2473 // Prepare IV data that we will use during confirm packet encryption.
2474 randomZRTP(randomIV, sizeof(randomIV));
2475 zrtpSasRelay.setIv(randomIV);
2476 zrtpSasRelay.setTrustedSas(sh);
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002477 zrtpSasRelay.setSasAlgo((uint8_t*)render.c_str());
Alexandre Lision51140e12013-12-02 10:54:09 -05002478
Alexandre Lision51140e12013-12-02 10:54:09 -05002479 int16_t hmlen = (zrtpSasRelay.getLength() - 9) * ZRTP_WORD_SIZE;
2480 cipher->getEncrypt()(ekey, cipher->getKeylen(), randomIV, (uint8_t*)zrtpSasRelay.getFiller(), hmlen);
2481
2482 // Use negotiated HMAC (hash)
2483 hmacFunction(hkey, hashLength, (unsigned char*)zrtpSasRelay.getFiller(), hmlen, confMac, &macLen);
2484
2485 zrtpSasRelay.setHmac(confMac);
2486
2487 stateEngine->sendSASRelay(&zrtpSasRelay);
2488 return true;
2489}
2490
2491std::string ZRtp::getSasType() {
2492 std::string sasT(sasType->getName());
2493 return sasT;
2494}
2495
2496uint8_t* ZRtp::getSasHash() {
2497 return sasHash;
2498}
2499
2500int32_t ZRtp::getPeerZid(uint8_t* data) {
2501 memcpy(data, peerZid, IDENTIFIER_LEN);
2502 return IDENTIFIER_LEN;
2503}
2504
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002505const ZRtp::zrtpInfo* ZRtp::getDetailInfo() {
2506 return &detailInfo;
2507}
2508
2509std::string ZRtp::getPeerClientId() {
2510 if (peerClientId.empty())
2511 return std::string();
2512 return peerClientId;
2513}
2514
2515std::string ZRtp::getPeerProtcolVersion() {
2516 if (peerHelloVersion[0] == 0)
2517 return std::string();
2518 return std::string((char*)peerHelloVersion);
2519}
2520
Alexandre Lision51140e12013-12-02 10:54:09 -05002521/** EMACS **
2522 * Local variables:
2523 * mode: c++
2524 * c-default-style: ellemtel
2525 * c-basic-offset: 4
2526 * End:
2527 */
2528