bzrtpParserTest.c 112 KB
Newer Older
johan's avatar
johan committed
1 2 3 4 5 6 7
/**
 @file bzrtpParserTests.c
 @brief Test parsing and building ZRTP packet.

 @author Johan Pascal

 @copyright Copyright (C) 2014 Belledonne Communications, Grenoble, France
8

johan's avatar
johan committed
9 10 11 12
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.
13

johan's avatar
johan committed
14 15 16 17
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
18

johan's avatar
johan committed
19 20 21 22 23 24 25 26 27
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "CUnit/Basic.h"
28

29
#ifndef _WIN32
30
#include <time.h>
31 32 33
#else
#include <windows.h>
#endif
johan's avatar
johan committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47

#include "bzrtp/bzrtp.h"
#include "typedef.h"
#include "packetParser.h"
#include "cryptoUtils.h"
#include "zidCache.h"
#include "testUtils.h"


/**
 * Test pattern : the packet data in the patternZRTPPackets, length, sequence number and SSRC in patternZRTPMetaData
 * Pattern generated from wireshark trace
 *
 */
48
#define TEST_PACKET_NUMBER 9
johan's avatar
johan committed
49 50
/* meta data: length, sequence number, SSRC */
static uint32_t patternZRTPMetaData[TEST_PACKET_NUMBER][3] = {
51 52 53 54 55 56 57 58 59
	{136, 0x09f1, 0x12345678}, /* hello */
	{136, 0x02ce, 0x87654321}, /* hello */
	{28, 0x09f2, 0x12345678}, /* hello ack */
	{132, 0x02d0, 0x87654321}, /* commit */
	{484, 0x09f5, 0x12345678}, /* dhpart1 */
	{484, 0x02d1, 0x87654321}, /* dhpart2 */
	{92, 0x09f6, 0x12345678}, /* confirm 1 */
	{92, 0x02d2, 0x87654321}, /* confirm 2 */
	{28, 0x09f7, 0x12345678} /* conf2ACK*/
johan's avatar
johan committed
60 61 62
};

static const uint8_t patternZRTPPackets[TEST_PACKET_NUMBER][512] = {
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
	/* This is a Hello packet, sequence number is 0x09f1, SSRC 0x12345678 */
	{0x10, 0x00, 0x09, 0xf1, 0x5a, 0x52, 0x54, 0x50, 0x12, 0x34, 0x56, 0x78, 0x50, 0x5a, 0x00, 0x1e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x20, 0x20, 0x31, 0x2e, 0x31, 0x30, 0x4c, 0x49, 0x4e, 0x50, 0x48, 0x4f, 0x4e, 0x45, 0x2d, 0x5a, 0x52, 0x54, 0x50, 0x43, 0x50, 0x50, 0xe8, 0xd5, 0x26, 0xc1, 0x3a, 0x0c, 0x4c, 0x6a, 0xce, 0x18, 0xaa, 0xc7, 0xc4, 0xa4, 0x07, 0x0e, 0x65, 0x7a, 0x4d, 0xca, 0x78, 0xf2, 0xcc, 0xcd, 0x20, 0x50, 0x38, 0x73, 0xe9, 0x7e, 0x08, 0x29, 0x7e, 0xb0, 0x04, 0x97, 0xc0, 0xfe, 0xb2, 0xc9, 0x24, 0x31, 0x49, 0x7f, 0x00, 0x01, 0x12, 0x31, 0x53, 0x32, 0x35, 0x36, 0x41, 0x45, 0x53, 0x31, 0x48, 0x53, 0x33, 0x32, 0x48, 0x53, 0x38, 0x30, 0x44, 0x48, 0x33, 0x6b, 0x44, 0x48, 0x32, 0x6b, 0x4d, 0x75, 0x6c, 0x74, 0x42, 0x33, 0x32, 0x20, 0xa0, 0xfd, 0x0f, 0xad, 0xeb, 0xe0, 0x86, 0x56, 0xe3, 0x65, 0x81, 0x02},
	/* This is a Hello packet, sequence number is 0x02ce, SSRC 0x87654321 */
	{0x10, 0x00, 0x02, 0xce, 0x5a, 0x52, 0x54, 0x50, 0x87, 0x65, 0x43, 0x21, 0x50, 0x5a, 0x00, 0x1e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x20, 0x20, 0x31, 0x2e, 0x31, 0x30, 0x4c, 0x49, 0x4e, 0x50, 0x48, 0x4f, 0x4e, 0x45, 0x2d, 0x5a, 0x52, 0x54, 0x50, 0x43, 0x50, 0x50, 0x8d, 0x0f, 0x5a, 0x20, 0x79, 0x97, 0x42, 0x01, 0x99, 0x45, 0x45, 0xf7, 0x0e, 0x31, 0x06, 0xe1, 0x05, 0xc0, 0xb9, 0x24, 0xe9, 0xc9, 0x78, 0xc7, 0x38, 0xf5, 0x97, 0x48, 0xef, 0x42, 0x6a, 0x3e, 0x92, 0x42, 0xc2, 0xcf, 0x44, 0xee, 0x9c, 0x65, 0xca, 0x58, 0x78, 0xf1, 0x00, 0x01, 0x12, 0x31, 0x53, 0x32, 0x35, 0x36, 0x41, 0x45, 0x53, 0x31, 0x48, 0x53, 0x33, 0x32, 0x48, 0x53, 0x38, 0x30, 0x44, 0x48, 0x33, 0x6b, 0x44, 0x48, 0x32, 0x6b, 0x4d, 0x75, 0x6c, 0x74, 0x42, 0x33, 0x32, 0x20, 0xb3, 0x90, 0x91, 0x95, 0xe4, 0x67, 0xa3, 0x21, 0xe3, 0x5f, 0x9c, 0x92},
	/* This is a Hello ack packet, sequence number is 0x09f2, SSRC 0x12345678*/
	{0x10, 0x00, 0x09, 0xf2, 0x5a, 0x52, 0x54, 0x50, 0x12, 0x34, 0x56, 0x78, 0x50, 0x5a, 0x00, 0x03, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x41, 0x43, 0x4b, 0x77, 0x0e, 0x44, 0x07},
	/* This is a Commit packet, sequence number is 0x02d0, SSRC 0x87654321 */
	{0x10, 0x00, 0x02, 0xd0, 0x5a, 0x52, 0x54, 0x50, 0x87, 0x65, 0x43, 0x21, 0x50, 0x5a, 0x00, 0x1d, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x20, 0x20, 0xd9, 0xff, 0x14, 0x8b, 0x34, 0xaa, 0x69, 0xe9, 0x33, 0xc1, 0x62, 0xe6, 0x6b, 0xe8, 0xcd, 0x9d, 0xe3, 0x0f, 0xb7, 0x6a, 0xe8, 0x6a, 0x62, 0x2b, 0xcb, 0xe4, 0x6b, 0x91, 0x05, 0xc7, 0xc8, 0x7e, 0x92, 0x42, 0xc2, 0xcf, 0x44, 0xee, 0x9c, 0x65, 0xca, 0x58, 0x78, 0xf1, 0x53, 0x32, 0x35, 0x36, 0x41, 0x45, 0x53, 0x31, 0x48, 0x53, 0x33, 0x32, 0x44, 0x48, 0x33, 0x6b, 0x42, 0x33, 0x32, 0x20, 0x1e, 0xc0, 0xfe, 0x2e, 0x72, 0x06, 0x4d, 0xfb, 0xfc, 0x92, 0x02, 0x8c, 0x03, 0x0f, 0xb8, 0xf8, 0x91, 0xb4, 0xe7, 0x96, 0xac, 0x25, 0xfd, 0xf9, 0x68, 0xc6, 0xe9, 0x67, 0xa9, 0x42, 0xb1, 0x5b, 0xbb, 0x6d, 0x9c, 0xd2, 0x4b, 0x13, 0xa9, 0xae, 0x25, 0x5c, 0xa9, 0xc1},
	/* This is a DHPart1 packet, sequence number is 0x09f5, SSRC 0x12345678 */
	{0x10, 0x00, 0x09, 0xf5, 0x5a, 0x52, 0x54, 0x50, 0x12, 0x34, 0x56, 0x78, 0x50, 0x5a, 0x00, 0x75, 0x44, 0x48, 0x50, 0x61, 0x72, 0x74, 0x31, 0x20, 0x28, 0x7c, 0x28, 0xe4, 0xd7, 0x3d, 0x14, 0x39, 0xb5, 0x6d, 0x1c, 0x47, 0x9d, 0x59, 0x0a, 0xf2, 0x10, 0x33, 0xde, 0x6b, 0xd5, 0x2b, 0xfb, 0x26, 0xa5, 0x87, 0x4d, 0xe9, 0x20, 0x6b, 0x9f, 0xdd, 0xab, 0xbc, 0xc6, 0x8d, 0xbd, 0x5d, 0xe6, 0x67, 0x00, 0x69, 0x44, 0xb1, 0x84, 0x2c, 0x27, 0x10, 0x8c, 0x4e, 0x58, 0x8a, 0xed, 0x7e, 0x8b, 0x44, 0x2c, 0x3a, 0x13, 0x02, 0xdf, 0x58, 0xb6, 0xda, 0x80, 0x55, 0xec, 0xb0, 0x20, 0xc7, 0x76, 0x50, 0xc4, 0x1b, 0xa8, 0x26, 0x11, 0x5c, 0xf5, 0x71, 0x7e, 0xb4, 0x86, 0x22, 0x17, 0xde, 0x14, 0x08, 0x46, 0x5c, 0xac, 0x88, 0x8c, 0x41, 0x6b, 0x95, 0x22, 0xba, 0xf8, 0x3e, 0x67, 0x20, 0x94, 0xa0, 0x84, 0xa3, 0x93, 0x41, 0x9a, 0x1a, 0x7c, 0x2f, 0x04, 0xf4, 0x14, 0x3f, 0x11, 0x54, 0x02, 0xba, 0xee, 0xc2, 0x20, 0xfa, 0x38, 0xf7, 0xba, 0xa4, 0xbf, 0x4a, 0x70, 0x02, 0x68, 0xdc, 0xb2, 0xe9, 0x1a, 0x8a, 0x87, 0xa5, 0xe4, 0x9c, 0x42, 0x07, 0x82, 0x26, 0xb4, 0xda, 0xe3, 0x1b, 0xdc, 0x78, 0xc7, 0xd8, 0xa8, 0x00, 0x5c, 0x00, 0x14, 0xe4, 0x00, 0xfe, 0x6c, 0x2d, 0xce, 0x62, 0xc9, 0x71, 0x5d, 0xed, 0x4e, 0x66, 0x9f, 0xf5, 0x30, 0xc0, 0x04, 0x53, 0xf6, 0x15, 0x2f, 0xe1, 0x85, 0x3b, 0xd9, 0x40, 0x9b, 0x50, 0x07, 0x43, 0x7c, 0x36, 0x01, 0xa1, 0xda, 0x66, 0xc4, 0x20, 0x2f, 0x45, 0xc0, 0xcc, 0xb2, 0x64, 0x63, 0x9c, 0x07, 0x9d, 0x23, 0x27, 0x80, 0xa1, 0x7f, 0xc2, 0xe0, 0xa0, 0xfd, 0xc3, 0x98, 0x83, 0xa3, 0xaa, 0x6b, 0xdc, 0x9f, 0x6a, 0xc3, 0x32, 0x94, 0xf0, 0x80, 0xa0, 0xd9, 0xf1, 0x83, 0x41, 0x48, 0xa9, 0xb5, 0xed, 0x62, 0x50, 0x88, 0xec, 0x33, 0x32, 0xd2, 0x5f, 0xdc, 0xcc, 0xae, 0xc9, 0x74, 0xca, 0x0a, 0xab, 0x82, 0x06, 0x01, 0x46, 0x35, 0x30, 0xcd, 0x68, 0xec, 0x09, 0xab, 0x8c, 0xb0, 0x39, 0xe5, 0xd8, 0x5c, 0xa2, 0xe4, 0x82, 0xfe, 0x46, 0x01, 0xbd, 0xe7, 0x7f, 0x60, 0x1b, 0x50, 0x62, 0xfb, 0x6f, 0xee, 0x6c, 0xf1, 0xf7, 0x9b, 0xb7, 0x1c, 0x76, 0x48, 0xb5, 0xbe, 0xa5, 0x83, 0x73, 0x07, 0xa2, 0xe2, 0x73, 0xc7, 0x68, 0x34, 0xc8, 0xef, 0x12, 0xc4, 0x32, 0xdf, 0x37, 0x3d, 0xdc, 0x07, 0x0e, 0xa6, 0x92, 0x82, 0xbd, 0xba, 0x20, 0xc4, 0xb4, 0x8d, 0x1f, 0x19, 0x1c, 0x15, 0x0f, 0x5f, 0x01, 0xdf, 0x67, 0x1f, 0x59, 0xd1, 0x5e, 0x99, 0x60, 0xf6, 0xb8, 0x67, 0xe2, 0x46, 0x62, 0x11, 0x30, 0xfb, 0x81, 0x9d, 0x0b, 0xec, 0x36, 0xe9, 0x8d, 0x43, 0xfe, 0x55, 0xd9, 0x61, 0x98, 0x3f, 0x2e, 0x39, 0x6a, 0x26, 0x43, 0xb0, 0x6d, 0x08, 0xec, 0x2e, 0x42, 0x7e, 0x23, 0x82, 0x6f, 0xd9, 0xbb, 0xfd, 0x0a, 0xcd, 0x48, 0xe7, 0xd5, 0x8b, 0xa5, 0x80, 0x34, 0xca, 0x96, 0x4f, 0x58, 0x25, 0xba, 0x43, 0x5e, 0x3d, 0x1c, 0xee, 0x72, 0xb8, 0x35, 0x8c, 0x5d, 0xd9, 0x69, 0x24, 0x58, 0x36, 0x21, 0xb0, 0x45, 0xa4, 0xad, 0x40, 0xda, 0x94, 0x98, 0x0f, 0xb1, 0xed, 0x6c, 0xad, 0x26, 0x03, 0x04, 0x82, 0xff, 0x15, 0x00, 0x41, 0x87, 0x06, 0x93, 0xd4, 0x86, 0xa9, 0x7e, 0xb8, 0xd9, 0x70, 0x34, 0x6d, 0x8e, 0x6a, 0x16, 0xe2, 0x46, 0x52, 0xb0, 0x78, 0x54, 0x53, 0xaf},
	/* This is a DHPart2 packet, sequence number is 0x02d1, SSRC 0x87654321 */
	{0x10, 0x00, 0x02, 0xd1, 0x5a, 0x52, 0x54, 0x50, 0x87, 0x65, 0x43, 0x21, 0x50, 0x5a, 0x00, 0x75, 0x44, 0x48, 0x50, 0x61, 0x72, 0x74, 0x32, 0x20, 0x9e, 0xb2, 0xa5, 0x8b, 0xe8, 0x96, 0x37, 0xf5, 0x5a, 0x41, 0x34, 0xb2, 0xec, 0xda, 0x84, 0x95, 0xf0, 0xf8, 0x9b, 0xab, 0x61, 0x4f, 0x7c, 0x9e, 0x56, 0xb7, 0x3b, 0xd3, 0x46, 0xba, 0xbe, 0x9a, 0xae, 0x97, 0x97, 0xda, 0x5f, 0x9f, 0x89, 0xba, 0xfe, 0x61, 0x66, 0x5f, 0x9e, 0xa4, 0x5b, 0xcb, 0xd5, 0x69, 0xcf, 0xfb, 0xfd, 0xdc, 0xac, 0x79, 0xac, 0x1d, 0x0b, 0xe5, 0x15, 0x75, 0x39, 0x2e, 0xe5, 0xa9, 0x2a, 0x60, 0xd7, 0xe3, 0x48, 0xd0, 0x1f, 0xd8, 0x61, 0x65, 0xfd, 0x2e, 0x5c, 0xef, 0x43, 0xf5, 0x63, 0x99, 0xb3, 0x45, 0x25, 0xe3, 0xbc, 0xf0, 0xe1, 0xad, 0xf7, 0x84, 0xcd, 0x82, 0x20, 0xe3, 0x6f, 0x2c, 0x77, 0x51, 0xf1, 0x11, 0x2e, 0x4a, 0x2c, 0xfd, 0x2f, 0x5e, 0x74, 0xa9, 0x37, 0x99, 0xff, 0xf7, 0x4c, 0x2d, 0xa8, 0xcf, 0x51, 0xfd, 0x5b, 0xe7, 0x51, 0x14, 0x6d, 0xbc, 0x2f, 0x5b, 0xb9, 0x77, 0x85, 0xad, 0xb4, 0x72, 0x99, 0xad, 0x7b, 0x6c, 0x6a, 0xdf, 0x4d, 0xca, 0x2f, 0xef, 0x8b, 0x5e, 0x4b, 0xf3, 0xd9, 0xfd, 0xbd, 0x47, 0x1a, 0x72, 0xe2, 0x41, 0xd8, 0xfa, 0xa1, 0x25, 0x00, 0xa3, 0xfe, 0x12, 0xda, 0xf6, 0x16, 0xb3, 0xb3, 0x08, 0x02, 0xfd, 0x0a, 0x6a, 0xab, 0x85, 0x17, 0xd7, 0x0f, 0xf4, 0x6b, 0xdf, 0x8f, 0xe2, 0x05, 0xf4, 0x5b, 0x13, 0x26, 0xa9, 0xe2, 0x57, 0xb6, 0xda, 0x76, 0x17, 0x3c, 0x52, 0x13, 0x8d, 0x83, 0xc0, 0x2b, 0xe7, 0x2e, 0xbd, 0xb0, 0xde, 0x98, 0x4f, 0x7a, 0x95, 0xa1, 0x75, 0x19, 0x6e, 0xda, 0x19, 0xff, 0x7f, 0xdd, 0x70, 0x01, 0x12, 0x3c, 0x9e, 0xd7, 0xfe, 0xc3, 0x22, 0x39, 0xce, 0x4f, 0x86, 0xd8, 0x85, 0x40, 0x75, 0xd4, 0xfe, 0x93, 0x57, 0xbc, 0x9b, 0x01, 0xa4, 0x71, 0x35, 0x70, 0x9d, 0x62, 0x91, 0x47, 0x4e, 0x32, 0xa2, 0x76, 0x16, 0x06, 0xaf, 0xc7, 0xe3, 0xe5, 0xdc, 0x25, 0xac, 0xe7, 0x68, 0x25, 0x69, 0x0f, 0x97, 0x8d, 0x91, 0x32, 0x81, 0x23, 0xb1, 0x08, 0xf3, 0xa3, 0x2b, 0x3d, 0xfb, 0xcf, 0x99, 0x12, 0x0a, 0x59, 0xb9, 0xbb, 0x76, 0x16, 0x71, 0xa2, 0x0b, 0x0a, 0x5a, 0x6c, 0x37, 0x99, 0x9d, 0xe6, 0x3a, 0x05, 0x89, 0xf7, 0xc6, 0xfc, 0xf3, 0xfe, 0x36, 0x97, 0x77, 0x86, 0xe4, 0x7c, 0x48, 0x93, 0x0b, 0x26, 0x8e, 0x31, 0xe9, 0x22, 0xcc, 0xd3, 0xe0, 0x56, 0x29, 0xc8, 0x26, 0xe6, 0x1f, 0xa8, 0xb8, 0x93, 0x98, 0xec, 0xd9, 0x7c, 0x4a, 0x45, 0xd3, 0x71, 0x35, 0x9f, 0x14, 0xc1, 0x99, 0xd5, 0x21, 0x0b, 0xfa, 0x0f, 0xfb, 0x31, 0x7a, 0xa0, 0x70, 0x35, 0xb3, 0x9b, 0x1b, 0xe7, 0x65, 0xfd, 0xe3, 0x7d, 0x0b, 0xcc, 0x34, 0x4b, 0xf1, 0x5a, 0x9f, 0x19, 0xa4, 0x8f, 0xc8, 0x30, 0xf1, 0x87, 0x99, 0xc2, 0x75, 0x55, 0x2a, 0x34, 0xd7, 0x81, 0x9c, 0x54, 0x12, 0x82, 0x69, 0x5f, 0x8b, 0x01, 0xc1, 0x45, 0x95, 0xf5, 0xb1, 0x2d, 0x27, 0x0d, 0xa9, 0xc3, 0x93, 0x54, 0x2f, 0x57, 0x04, 0x7b, 0x20, 0xb7, 0xac, 0x33, 0x68, 0xb3, 0xef, 0x9a, 0x33, 0x95, 0x82, 0x9d, 0xfa, 0x2a, 0xb9, 0x88, 0x06, 0x04, 0x88, 0x51, 0x2c, 0x46, 0xdb, 0x83, 0xd7, 0x2f, 0xea, 0x1f, 0x0f, 0x24, 0xab, 0x03, 0xef, 0xb0, 0x61, 0xc7, 0x90, 0xdc, 0x78, 0x17, 0xf2, 0x9a, 0xab},
	/* This is a confirm1 packet, sequence number is 0x09f6, SSRC 0x12345678 */
	{0x10, 0x00, 0x09, 0xf6, 0x5a, 0x52, 0x54, 0x50, 0x12, 0x34, 0x56, 0x78, 0x50, 0x5a, 0x00, 0x13, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x31, 0xb1, 0x21, 0xee, 0xe2, 0x67, 0xa4, 0xfd, 0xa6, 0x94, 0x24, 0x9a, 0x60, 0xf0, 0x2e, 0x5e, 0xd9, 0x33, 0xe1, 0xd8, 0x41, 0x54, 0xa3, 0x7c, 0xea, 0xe9, 0x61, 0xae, 0xf9, 0x19, 0x0d, 0xb3, 0x68, 0x68, 0x9e, 0xf8, 0x1a, 0x18, 0x91, 0x87, 0xc5, 0x6e, 0x5e, 0x2d, 0x5e, 0x32, 0xa2, 0xb2, 0x66, 0x31, 0xb8, 0xe5, 0x59, 0xc9, 0x10, 0xbb, 0xa0, 0x00, 0x6c, 0xee, 0x0c, 0x6d, 0xfb, 0xeb, 0x32, 0x85, 0xb6, 0x6e, 0x93},
	/* This is a confirm2 packet, sequence number is 0x02d2, SSRC 0x87654321 */
	{0x10, 0x00, 0x02, 0xd2, 0x5a, 0x52, 0x54, 0x50, 0x87, 0x65, 0x43, 0x21, 0x50, 0x5a, 0x00, 0x13, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x32, 0x0f, 0xec, 0xfa, 0x4b, 0x45, 0x17, 0x9d, 0xb3, 0x92, 0x7d, 0x1c, 0x53, 0x86, 0x01, 0x12, 0xd9, 0x25, 0x48, 0xca, 0x18, 0xb9, 0x10, 0x95, 0x04, 0xb7, 0xc8, 0xee, 0x87, 0x2b, 0xec, 0x59, 0x39, 0x92, 0x96, 0x11, 0x73, 0xa6, 0x69, 0x2b, 0x11, 0xcd, 0x1d, 0xa1, 0x73, 0xb2, 0xc9, 0x29, 0x6f, 0x82, 0x32, 0x6a, 0x0a, 0x56, 0x40, 0x57, 0xfb, 0xac, 0xab, 0x20, 0xb8, 0xe2, 0xa9, 0x2c, 0x61, 0x6a, 0x05, 0xe8, 0xb5},
	/* This is a conf2ACK packet, sequence number 0x09f7, SSRC 0x12345678 */
	{0x10, 0x00, 0x09, 0xf7, 0x5a, 0x52, 0x54, 0x50, 0x12, 0x34, 0x56, 0x78, 0x50, 0x5a, 0x00, 0x03, 0x43, 0x6f, 0x6e, 0x66, 0x32, 0x41, 0x43, 0x4b, 0x23, 0xc1, 0x1b, 0x45},
johan's avatar
johan committed
81 82 83
};

/* Hash images for both sides */
84 85 86 87 88
uint8_t H12345678[4][32] = {
	{0xbb, 0xbf, 0x7e, 0xb1, 0x14, 0xd5, 0xd4, 0x0c, 0x6b, 0xb0, 0x79, 0x58, 0x19, 0xc1, 0xd0, 0x83, 0xc9, 0xe1, 0xf4, 0x2e, 0x11, 0xcd, 0x7e, 0xc3, 0xaa, 0xd8, 0xb9, 0x17, 0xe6, 0xb5, 0x9e, 0x86},
	{0x28, 0x7c, 0x28, 0xe4, 0xd7, 0x3d, 0x14, 0x39, 0xb5, 0x6d, 0x1c, 0x47, 0x9d, 0x59, 0x0a, 0xf2, 0x10, 0x33, 0xde, 0x6b, 0xd5, 0x2b, 0xfb, 0x26, 0xa5, 0x87, 0x4d, 0xe9, 0x20, 0x6b, 0x9f, 0xdd},
	{0x70, 0x12, 0xef, 0x2e, 0x85, 0x2f, 0xfc, 0x84, 0xb8, 0x8d, 0xcc, 0x03, 0xd7, 0x8f, 0x53, 0x01, 0x63, 0xfb, 0xd3, 0xb0, 0x2d, 0xbb, 0x9e, 0x98, 0x22, 0x0d, 0xe3, 0xe3, 0x64, 0x25, 0x04, 0x0f},
	{0xe8, 0xd5, 0x26, 0xc1, 0x3a, 0x0c, 0x4c, 0x6a, 0xce, 0x18, 0xaa, 0xc7, 0xc4, 0xa4, 0x07, 0x0e, 0x65, 0x7a, 0x4d, 0xca, 0x78, 0xf2, 0xcc, 0xcd, 0x20, 0x50, 0x38, 0x73, 0xe9, 0x7e, 0x08, 0x29}
johan's avatar
johan committed
89 90
};

91 92 93 94 95 96 97 98 99 100 101 102
uint8_t H87654321[4][32] = {
	{0x09, 0x02, 0xcc, 0x13, 0xc4, 0x84, 0x03, 0x31, 0x68, 0x91, 0x05, 0x4d, 0xe0, 0x6d, 0xf4, 0xc9, 0x6a, 0xb5, 0xbe, 0x82, 0xe8, 0x37, 0x33, 0xb7, 0xa9, 0xce, 0xbe, 0xb5, 0x42, 0xaa, 0x54, 0xba},
	{0x9e, 0xb2, 0xa5, 0x8b, 0xe8, 0x96, 0x37, 0xf5, 0x5a, 0x41, 0x34, 0xb2, 0xec, 0xda, 0x84, 0x95, 0xf0, 0xf8, 0x9b, 0xab, 0x61, 0x4f, 0x7c, 0x9e, 0x56, 0xb7, 0x3b, 0xd3, 0x46, 0xba, 0xbe, 0x9a},
	{0xd9, 0xff, 0x14, 0x8b, 0x34, 0xaa, 0x69, 0xe9, 0x33, 0xc1, 0x62, 0xe6, 0x6b, 0xe8, 0xcd, 0x9d, 0xe3, 0x0f, 0xb7, 0x6a, 0xe8, 0x6a, 0x62, 0x2b, 0xcb, 0xe4, 0x6b, 0x91, 0x05, 0xc7, 0xc8, 0x7e},
	{0x8d, 0x0f, 0x5a, 0x20, 0x79, 0x97, 0x42, 0x01, 0x99, 0x45, 0x45, 0xf7, 0x0e, 0x31, 0x06, 0xe1, 0x05, 0xc0, 0xb9, 0x24, 0xe9, 0xc9, 0x78, 0xc7, 0x38, 0xf5, 0x97, 0x48, 0xef, 0x42, 0x6a, 0x3e}
};

/* mac and zrtp keys */
uint8_t mackeyi[32] = {0xdc, 0x47, 0xe1, 0xc7, 0x48, 0x11, 0xb1, 0x54, 0x14, 0x2a, 0x91, 0x29, 0x9f, 0xa4, 0x8b, 0x45, 0x87, 0x16, 0x8d, 0x3a, 0xe6, 0xb0, 0x0c, 0x08, 0x4f, 0xa5, 0x48, 0xd5, 0x96, 0x67, 0x1a, 0x1b};
uint8_t mackeyr[32] = {0x3a, 0xa5, 0x22, 0x43, 0x26, 0x13, 0x8f, 0xd6, 0x54, 0x59, 0x40, 0xb8, 0x5c, 0xf4, 0x0f, 0x0c, 0xbc, 0x9c, 0x4f, 0x7d, 0x55, 0xeb, 0x4b, 0xa5, 0x1e, 0x1c, 0x42, 0xd0, 0x5e, 0xac, 0x12, 0x06};
uint8_t zrtpkeyi[16] = {0x22, 0xf6, 0xea, 0xaa, 0xa4, 0xad, 0x53, 0x30, 0x71, 0x97, 0xcc, 0x68, 0x6b, 0xb0, 0xcb, 0x55};
uint8_t zrtpkeyr[16] = {0x09, 0x50, 0xcd, 0x9e, 0xc2, 0x78, 0x54, 0x31, 0x93, 0x2e, 0x99, 0x31, 0x15, 0x58, 0xd0, 0x2a};
johan's avatar
johan committed
103

104 105

void test_parser_param(uint8_t hvi_trick) {
johan's avatar
johan committed
106 107
	int i, retval;
	bzrtpPacket_t *zrtpPacket;
108

109 110 111
	/* Create zrtp Context to use H0-H3 chains and others */
	bzrtpContext_t *context87654321 = bzrtp_createBzrtpContext(0x87654321);
	bzrtpContext_t *context12345678 = bzrtp_createBzrtpContext(0x12345678);
johan's avatar
johan committed
112 113 114


	/* replace created H by the patterns one to be able to generate the correct packet */
115 116 117 118 119 120 121 122
	memcpy (context12345678->channelContext[0]->selfH[0], H12345678[0], 32);
	memcpy (context12345678->channelContext[0]->selfH[1], H12345678[1], 32);
	memcpy (context12345678->channelContext[0]->selfH[2], H12345678[2], 32);
	memcpy (context12345678->channelContext[0]->selfH[3], H12345678[3], 32);
	memcpy (context87654321->channelContext[0]->selfH[0], H87654321[0], 32);
	memcpy (context87654321->channelContext[0]->selfH[1], H87654321[1], 32);
	memcpy (context87654321->channelContext[0]->selfH[2], H87654321[2], 32);
	memcpy (context87654321->channelContext[0]->selfH[3], H87654321[3], 32);
johan's avatar
johan committed
123 124

	/* preset the key agreement algo in the contexts */
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
	context87654321->channelContext[0]->keyAgreementAlgo = ZRTP_KEYAGREEMENT_DH3k;
	context12345678->channelContext[0]->keyAgreementAlgo = ZRTP_KEYAGREEMENT_DH3k;
	context87654321->channelContext[0]->cipherAlgo = ZRTP_CIPHER_AES1;
	context12345678->channelContext[0]->cipherAlgo = ZRTP_CIPHER_AES1;
	context87654321->channelContext[0]->hashAlgo = ZRTP_HASH_S256;
	context12345678->channelContext[0]->hashAlgo = ZRTP_HASH_S256;

	updateCryptoFunctionPointers(context87654321->channelContext[0]);
	updateCryptoFunctionPointers(context12345678->channelContext[0]);

	/* set the zrtp and mac keys */
	context87654321->channelContext[0]->mackeyi = (uint8_t *)malloc(32);
	context12345678->channelContext[0]->mackeyi = (uint8_t *)malloc(32);
	context87654321->channelContext[0]->mackeyr = (uint8_t *)malloc(32);
	context12345678->channelContext[0]->mackeyr = (uint8_t *)malloc(32);

	context87654321->channelContext[0]->zrtpkeyi = (uint8_t *)malloc(16);
	context12345678->channelContext[0]->zrtpkeyi = (uint8_t *)malloc(16);
	context87654321->channelContext[0]->zrtpkeyr = (uint8_t *)malloc(16);
	context12345678->channelContext[0]->zrtpkeyr = (uint8_t *)malloc(16);

	memcpy(context12345678->channelContext[0]->mackeyi, mackeyi, 32);
	memcpy(context12345678->channelContext[0]->mackeyr, mackeyr, 32);
	memcpy(context12345678->channelContext[0]->zrtpkeyi, zrtpkeyi, 16);
	memcpy(context12345678->channelContext[0]->zrtpkeyr, zrtpkeyr, 16);
	memcpy(context87654321->channelContext[0]->mackeyi, mackeyi, 32);
	memcpy(context87654321->channelContext[0]->mackeyr, mackeyr, 32);
	memcpy(context87654321->channelContext[0]->zrtpkeyi, zrtpkeyi, 16);
	memcpy(context87654321->channelContext[0]->zrtpkeyr, zrtpkeyr, 16);

	/* set the role: 87654321 is initiator in our exchange pattern */
156
	context12345678->channelContext[0]->role = RESPONDER;
johan's avatar
johan committed
157 158

	for (i=0; i<TEST_PACKET_NUMBER; i++) {
159
		uint8_t freePacketFlag = 1;
johan's avatar
johan committed
160 161
		/* parse a packet string from patterns */
		zrtpPacket = bzrtp_packetCheck(patternZRTPPackets[i], patternZRTPMetaData[i][0], (patternZRTPMetaData[i][1])-1, &retval);
162
		retval +=  bzrtp_packetParser((patternZRTPMetaData[i][2]==0x87654321)?context12345678:context87654321, (patternZRTPMetaData[i][2]==0x87654321)?context12345678->channelContext[0]:context87654321->channelContext[0], patternZRTPPackets[i], patternZRTPMetaData[i][0], zrtpPacket);
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
		if (hvi_trick==0) {
			CU_ASSERT_EQUAL_FATAL(retval,0);
		} else { /* when hvi trick is enable, the DH2 parsing shall fail and return BZRTP_PARSER_ERROR_UNMATCHINGHVI */
			if (zrtpPacket->messageType==MSGTYPE_DHPART2) {
				CU_ASSERT_EQUAL_FATAL(retval, BZRTP_PARSER_ERROR_UNMATCHINGHVI);
				/* We shall then anyway skip the end of the test */
				/* reset pointers to selfHello packet in order to avoid double free */
				context87654321->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = NULL;
				context12345678->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = NULL;

				bzrtp_destroyBzrtpContext(context87654321, 0x87654321);
				bzrtp_destroyBzrtpContext(context12345678, 0x12345678);

				return;

			} else {
				CU_ASSERT_EQUAL_FATAL(retval,0);
			}
		}
			bzrtp_message("parsing Ret val is %x index is %d\n", retval, i);
183 184 185 186
		/* We must store some packets in the context if we want to be able to parse further packets */
		if (zrtpPacket->messageType==MSGTYPE_HELLO) {
			if (patternZRTPMetaData[i][2]==0x87654321) {
				context12345678->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket;
187
				context87654321->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket;
188 189
			} else {
				context87654321->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket;
190
				context12345678->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket;
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
			}
			freePacketFlag = 0;
		}
		if (zrtpPacket->messageType==MSGTYPE_COMMIT) {
			if (patternZRTPMetaData[i][2]==0x87654321) {
				context12345678->channelContext[0]->peerPackets[COMMIT_MESSAGE_STORE_ID] = zrtpPacket;
			} else {
				context87654321->channelContext[0]->peerPackets[COMMIT_MESSAGE_STORE_ID] = zrtpPacket;
			}
			freePacketFlag = 0;
		}
		if (zrtpPacket->messageType==MSGTYPE_DHPART1 || zrtpPacket->messageType==MSGTYPE_DHPART2) {
			if (patternZRTPMetaData[i][2]==0x87654321) {
				context12345678->channelContext[0]->peerPackets[DHPART_MESSAGE_STORE_ID] = zrtpPacket;
			} else {
				context87654321->channelContext[0]->peerPackets[DHPART_MESSAGE_STORE_ID] = zrtpPacket;
			}
			freePacketFlag = 0;
		}
johan's avatar
johan committed
210 211 212
		/* free the packet string as will be created again by the packetBuild function and might have been copied by packetParser */
		free(zrtpPacket->packetString);
		/* build a packet string from the parser packet*/
213 214
		retval = bzrtp_packetBuild((patternZRTPMetaData[i][2]==0x12345678)?context12345678:context87654321, (patternZRTPMetaData[i][2]==0x12345678)?context12345678->channelContext[0]:context87654321->channelContext[0], zrtpPacket, patternZRTPMetaData[i][1]);
		/* if (retval ==0) {
johan's avatar
johan committed
215 216
			packetDump(zrtpPacket, 1);
		} else {
johan's avatar
johan committed
217
			bzrtp_message("Ret val is %x index is %d\n", retval, i);
218
		}*/
johan's avatar
johan committed
219 220 221 222

		/* check they are the same */
		if (zrtpPacket->packetString != NULL) {
			CU_ASSERT_TRUE(memcmp(zrtpPacket->packetString, patternZRTPPackets[i], patternZRTPMetaData[i][0]) == 0);
223 224
		} else {
			CU_FAIL("Unable to build packet");
johan's avatar
johan committed
225 226
		}

227 228 229
		if (freePacketFlag == 1) {
			bzrtp_freeZrtpPacket(zrtpPacket);
		}
230 231 232 233 234 235 236 237 238 239 240 241

		/* modify the hvi stored in the peerPackets, this shall result in parsing failure on DH2 packet */
		if (hvi_trick == 1) {
			if (zrtpPacket->messageType==MSGTYPE_COMMIT) {
				if (patternZRTPMetaData[i][2]==0x87654321) {
					bzrtpCommitMessage_t *peerCommitMessageData;
					peerCommitMessageData = (bzrtpCommitMessage_t *)zrtpPacket->messageData;
					peerCommitMessageData->hvi[0]=0xFF;
				}
			}
		}

242
	}
johan's avatar
johan committed
243

244 245 246 247 248
	/* reset pointers to selfHello packet in order to avoid double free */
	context87654321->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = NULL;
	context12345678->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = NULL;


249 250
	bzrtp_destroyBzrtpContext(context87654321, 0x87654321);
	bzrtp_destroyBzrtpContext(context12345678, 0x12345678);
johan's avatar
johan committed
251 252 253

}

254 255 256 257 258 259 260 261
void test_parser(void) {
	test_parser_param(0);
}

void test_parser_hvi(void) {
	test_parser_param(1);
}

johan's avatar
johan committed
262 263 264 265 266 267 268
/* context structure mainly used by statemachine test, but also needed by parserComplete to get the zid Filename */
typedef struct my_Context_struct {
	unsigned char nom[30]; /* nom du contexte */
	bzrtpContext_t *peerContext;
	bzrtpChannelContext_t *peerChannelContext;
	char zidFilename[80]; /* nom du fichier de cache */
} my_Context_t;
johan's avatar
johan committed
269

Simon Morlat's avatar
Simon Morlat committed
270 271 272 273 274
static void freeBuf(void* p){
	free(p);
}

int floadAlice(void *clientData, uint8_t **output, uint32_t *size, zrtpFreeBuffer_callback *cb) {
johan's avatar
johan committed
275 276
	/* get filename from ClientData */
	my_Context_t *clientContext = (my_Context_t *)clientData;
277
	char *filename = clientContext->zidFilename;
johan's avatar
johan committed
278
	FILE *ALICECACHE = fopen(filename, "r+");
279 280 281
	fseek(ALICECACHE, 0L, SEEK_END);  /* Position to end of file */
  	*size = ftell(ALICECACHE);     /* Get file length */
  	rewind(ALICECACHE);               /* Back to start of file */
282
	*output = (uint8_t *)malloc(*size*sizeof(uint8_t)+1);
Simon Morlat's avatar
Simon Morlat committed
283 284 285
	if (fread(*output, 1, *size, ALICECACHE)==0){
		fprintf(stderr,"floadAlice() fread() error\n");
	}
286 287
	*(*output+*size) = '\0';
	*size += 1;
288
	fclose(ALICECACHE);
Simon Morlat's avatar
Simon Morlat committed
289
	*cb=freeBuf;
290
	return *size;
johan's avatar
johan committed
291 292
}

Simon Morlat's avatar
Simon Morlat committed
293
int fwriteAlice(void *clientData, const uint8_t *input, uint32_t size) {
johan's avatar
johan committed
294 295
	/* get filename from ClientData */
	my_Context_t *clientContext = (my_Context_t *)clientData;
296
	char *filename = clientContext->zidFilename;
johan's avatar
johan committed
297 298

	FILE *ALICECACHE = fopen(filename, "w+");
299 300 301
	int retval = fwrite(input, 1, size, ALICECACHE);
	fclose(ALICECACHE);
	return retval;
johan's avatar
johan committed
302 303
}

Simon Morlat's avatar
Simon Morlat committed
304
int floadBob(void *clientData, uint8_t **output, uint32_t *size, zrtpFreeBuffer_callback *cb) {
johan's avatar
johan committed
305 306
	/* get filename from ClientData */
	my_Context_t *clientContext = (my_Context_t *)clientData;
307
	char *filename = clientContext->zidFilename;
johan's avatar
johan committed
308 309

	FILE *BOBCACHE = fopen(filename, "r+");
310 311 312
	fseek(BOBCACHE, 0L, SEEK_END);  /* Position to end of file */
  	*size = ftell(BOBCACHE);     /* Get file length */
  	rewind(BOBCACHE);               /* Back to start of file */
313
	*output = (uint8_t *)malloc(*size*sizeof(uint8_t)+1);
Simon Morlat's avatar
Simon Morlat committed
314 315 316 317
	if (fread(*output, 1, *size, BOBCACHE)==0){
		fprintf(stderr,"floadBob(): fread error.\n");
		return -1;
	}
318 319
	*(*output+*size) = '\0';
	*size += 1;
320
	fclose(BOBCACHE);
Simon Morlat's avatar
Simon Morlat committed
321
	*cb=freeBuf;
322
	return *size;
johan's avatar
johan committed
323 324 325
}


Simon Morlat's avatar
Simon Morlat committed
326
int fwriteBob(void *clientData, const uint8_t *input, uint32_t size) {
johan's avatar
johan committed
327 328
	/* get filename from ClientData */
	my_Context_t *clientContext = (my_Context_t *)clientData;
329
	char *filename = clientContext->zidFilename;
johan's avatar
johan committed
330 331

	FILE *BOBCACHE = fopen(filename, "w+");
332 333 334
	int retval = fwrite(input, 1, size, BOBCACHE);
	fclose(BOBCACHE);
	return retval;
johan's avatar
johan committed
335 336 337 338 339 340 341 342 343 344
}

void test_parserComplete() {

	int retval;
	/* alice's maintained packet */
	bzrtpPacket_t *alice_Hello, *alice_HelloFromBob, *alice_HelloACK, *alice_HelloACKFromBob;
	/* bob's maintained packet */
	bzrtpPacket_t *bob_Hello, *bob_HelloFromAlice, *bob_HelloACK, *bob_HelloACKFromAlice;
	/* Create zrtp Context */
johan's avatar
johan committed
345 346
	bzrtpContext_t *contextAlice = bzrtp_createBzrtpContext(0x12345678); /* Alice's SSRC of main channel is 12345678 */
	bzrtpContext_t *contextBob = bzrtp_createBzrtpContext(0x87654321); /* Bob's SSRC of main channel is 87654321 */
johan's avatar
johan committed
347

348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
	bzrtpHelloMessage_t *alice_HelloFromBob_message;
	bzrtpHelloMessage_t *bob_HelloFromAlice_message;
	bzrtpPacket_t *alice_selfDHPart;
	bzrtpPacket_t *bob_selfDHPart;
	bzrtpPacket_t *alice_Commit;
	bzrtpPacket_t *bob_Commit;
	bzrtpPacket_t *bob_CommitFromAlice;
	bzrtpPacket_t *alice_CommitFromBob;
	uint8_t tmpBuffer[8];
	bzrtpDHPartMessage_t *bob_DHPart1;
	bzrtpPacket_t *alice_DHPart1FromBob;
	bzrtpDHPartMessage_t *alice_DHPart1FromBob_message=NULL;
	bzrtpPacket_t *bob_DHPart2FromAlice;
	bzrtpDHPartMessage_t *bob_DHPart2FromAlice_message=NULL;
	uint16_t secretLength;
	uint16_t totalHashDataLength;
	uint8_t *dataToHash;
	uint16_t hashDataIndex = 0;
	uint8_t alice_totalHash[32]; /* Note : actual length of hash depends on the choosen algo */
	uint8_t bob_totalHash[32]; /* Note : actual length of hash depends on the choosen algo */
	uint8_t *s1=NULL;
	uint32_t s1Length=0;
	uint8_t *s2=NULL;
	uint32_t s2Length=0;
	uint8_t *s3=NULL;
	uint32_t s3Length=0;
	uint8_t alice_sasHash[32];
	uint8_t bob_sasHash[32];
	uint32_t sasValue;
377
	char sas[32];
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
	bzrtpPacket_t *bob_Confirm1;
	bzrtpPacket_t *alice_Confirm1FromBob;
	bzrtpConfirmMessage_t *alice_Confirm1FromBob_message=NULL;
	bzrtpPacket_t *alice_Confirm2;
	bzrtpPacket_t *bob_Confirm2FromAlice;
	bzrtpConfirmMessage_t *bob_Confirm2FromAlice_message=NULL;
	bzrtpPacket_t *bob_Conf2ACK;
	bzrtpPacket_t *alice_Conf2ACKFromBob;
	bzrtpPacket_t *alice_Confirm1;
	bzrtpPacket_t *bob_Confirm1FromAlice;
	bzrtpConfirmMessage_t *bob_Confirm1FromAlice_message=NULL;
	bzrtpPacket_t *bob_Confirm2;
	bzrtpPacket_t *alice_Confirm2FromBob;
	bzrtpConfirmMessage_t *alice_Confirm2FromBob_message=NULL;
	bzrtpPacket_t *alice_Conf2ACK;
	bzrtpPacket_t *bob_Conf2ACKFromAlice;
Simon Morlat's avatar
Simon Morlat committed
394
	bzrtpCallbacks_t cbs={0};
395

johan's avatar
johan committed
396 397 398
	/* Create the client context, used for zidFilename only */
	my_Context_t clientContextAlice;
	my_Context_t clientContextBob;
399 400
	strcpy(clientContextAlice.zidFilename, "./ZIDAlice.txt");
	strcpy(clientContextBob.zidFilename, "./ZIDBob.txt");
johan's avatar
johan committed
401 402 403 404 405

	/* attach the clientContext to the bzrtp Context */
	retval = bzrtp_setClientData(contextAlice, 0x12345678, (void *)&clientContextAlice);
	retval += bzrtp_setClientData(contextBob, 0x87654321, (void *)&clientContextBob);

406
	/* set the cache related callback functions */
Simon Morlat's avatar
Simon Morlat committed
407 408
	cbs.bzrtp_loadCache=floadAlice;
	cbs.bzrtp_writeCache=fwriteAlice;
409

Simon Morlat's avatar
Simon Morlat committed
410
	bzrtp_setCallbacks(contextAlice, &cbs);
johan's avatar
johan committed
411

Simon Morlat's avatar
Simon Morlat committed
412 413 414
	cbs.bzrtp_loadCache=floadBob;
	cbs.bzrtp_writeCache=fwriteBob;
	bzrtp_setCallbacks(contextBob, &cbs);
johan's avatar
johan committed
415

johan's avatar
johan committed
416
	bzrtp_message ("Init the contexts\n");
johan's avatar
johan committed
417 418 419 420 421
	/* end the context init */
	bzrtp_initBzrtpContext(contextAlice);
	bzrtp_initBzrtpContext(contextBob);

	/* now create Alice and BOB Hello packet */
johan's avatar
johan committed
422 423 424 425
	alice_Hello = bzrtp_createZrtpPacket(contextAlice, contextAlice->channelContext[0], MSGTYPE_HELLO, &retval);
	if (bzrtp_packetBuild(contextAlice, contextAlice->channelContext[0], alice_Hello, contextAlice->channelContext[0]->selfSequenceNumber) ==0) {
		contextAlice->channelContext[0]->selfSequenceNumber++;
		contextAlice->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = alice_Hello;
johan's avatar
johan committed
426
	}
johan's avatar
johan committed
427 428 429 430
	bob_Hello = bzrtp_createZrtpPacket(contextBob, contextBob->channelContext[0], MSGTYPE_HELLO, &retval);
	if (bzrtp_packetBuild(contextBob, contextBob->channelContext[0], bob_Hello, contextBob->channelContext[0]->selfSequenceNumber) ==0) {
		contextBob->channelContext[0]->selfSequenceNumber++;
		contextBob->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = bob_Hello;
johan's avatar
johan committed
431 432 433
	}

	/* now send Alice Hello's to Bob and vice-versa, so they parse them */
johan's avatar
johan committed
434 435
	alice_HelloFromBob = bzrtp_packetCheck(bob_Hello->packetString, bob_Hello->messageLength+16, contextAlice->channelContext[0]->peerSequenceNumber, &retval);
	retval +=  bzrtp_packetParser(contextAlice, contextAlice->channelContext[0], bob_Hello->packetString, bob_Hello->messageLength+16, alice_HelloFromBob);
johan's avatar
johan committed
436
	bzrtp_message ("Alice parsing returns %x\n", retval);
johan's avatar
johan committed
437
	if (retval==0) {
438 439 440
		bzrtpHelloMessage_t *alice_HelloFromBob_message;
		int i;

johan's avatar
johan committed
441
		contextAlice->channelContext[0]->peerSequenceNumber = alice_HelloFromBob->sequenceNumber;
johan's avatar
johan committed
442
		/* save bob's Hello packet in Alice's context */
johan's avatar
johan committed
443
		contextAlice->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID] = alice_HelloFromBob;
johan's avatar
johan committed
444 445

		/* determine crypto Algo to use */
446
		alice_HelloFromBob_message = (bzrtpHelloMessage_t *)alice_HelloFromBob->messageData;
johan's avatar
johan committed
447
		retval = crypoAlgoAgreement(contextAlice, contextAlice->channelContext[0], contextAlice->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID]->messageData);
johan's avatar
johan committed
448
		if (retval == 0) {
johan's avatar
johan committed
449
			bzrtp_message ("Alice selected algo %x\n", contextAlice->channelContext[0]->keyAgreementAlgo);
johan's avatar
johan committed
450 451
			memcpy(contextAlice->peerZID, alice_HelloFromBob_message->ZID, 12);
		}
johan's avatar
johan committed
452 453 454 455 456 457 458

		/* check if the peer accept MultiChannel */
		for (i=0; i<alice_HelloFromBob_message->kc; i++) {
			if (alice_HelloFromBob_message->supportedKeyAgreement[i] == ZRTP_KEYAGREEMENT_Mult) {
				contextAlice->peerSupportMultiChannel = 1;
			}
		}
johan's avatar
johan committed
459 460
	}

johan's avatar
johan committed
461 462
	bob_HelloFromAlice = bzrtp_packetCheck(alice_Hello->packetString, alice_Hello->messageLength+16, contextBob->channelContext[0]->peerSequenceNumber, &retval);
	retval +=  bzrtp_packetParser(contextBob, contextBob->channelContext[0], alice_Hello->packetString, alice_Hello->messageLength+16, bob_HelloFromAlice);
johan's avatar
johan committed
463
	bzrtp_message ("Bob parsing returns %x\n", retval);
johan's avatar
johan committed
464
	if (retval==0) {
465 466 467
		bzrtpHelloMessage_t *bob_HelloFromAlice_message;
		int i;

johan's avatar
johan committed
468
		contextBob->channelContext[0]->peerSequenceNumber = bob_HelloFromAlice->sequenceNumber;
johan's avatar
johan committed
469
		/* save alice's Hello packet in bob's context */
johan's avatar
johan committed
470
		contextBob->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID] = bob_HelloFromAlice;
johan's avatar
johan committed
471 472

		/* determine crypto Algo to use */
473
		bob_HelloFromAlice_message = (bzrtpHelloMessage_t *)bob_HelloFromAlice->messageData;
johan's avatar
johan committed
474
		retval = crypoAlgoAgreement(contextBob, contextBob->channelContext[0], contextBob->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID]->messageData);
johan's avatar
johan committed
475
		if (retval == 0) {
johan's avatar
johan committed
476
			bzrtp_message ("Bob selected algo %x\n", contextBob->channelContext[0]->keyAgreementAlgo);
johan's avatar
johan committed
477 478 479
			memcpy(contextBob->peerZID, bob_HelloFromAlice_message->ZID, 12);
		}

johan's avatar
johan committed
480 481 482 483 484 485
		/* check if the peer accept MultiChannel */
		for (i=0; i<bob_HelloFromAlice_message->kc; i++) {
			if (bob_HelloFromAlice_message->supportedKeyAgreement[i] == ZRTP_KEYAGREEMENT_Mult) {
				contextBob->peerSupportMultiChannel = 1;
			}
		}
johan's avatar
johan committed
486 487 488
	}

	/* update context with hello message information : H3  and compute initiator and responder's shared secret Hashs */
489
	alice_HelloFromBob_message = (bzrtpHelloMessage_t *)alice_HelloFromBob->messageData;
johan's avatar
johan committed
490
	memcpy(contextAlice->channelContext[0]->peerH[3], alice_HelloFromBob_message->H3, 32);
491
	bob_HelloFromAlice_message = (bzrtpHelloMessage_t *)bob_HelloFromAlice->messageData;
johan's avatar
johan committed
492
	memcpy(contextBob->channelContext[0]->peerH[3], bob_HelloFromAlice_message->H3, 32);
johan's avatar
johan committed
493 494

	/* get the secrets associated to peer ZID */
495 496
	bzrtp_getPeerAssociatedSecretsHash(contextAlice, alice_HelloFromBob_message->ZID);
	bzrtp_getPeerAssociatedSecretsHash(contextBob, bob_HelloFromAlice_message->ZID);
johan's avatar
johan committed
497 498 499

	/* compute the initiator hashed secret as in rfc section 4.3.1 */
	if (contextAlice->cachedSecret.rs1!=NULL) {
johan's avatar
johan committed
500
		contextAlice->channelContext[0]->hmacFunction(contextAlice->cachedSecret.rs1, contextAlice->cachedSecret.rs1Length, (uint8_t *)"Initiator", 9, 8, contextAlice->initiatorCachedSecretHash.rs1ID);
johan's avatar
johan committed
501
	} else { /* we have no secret, generate a random */
502
		bctoolbox_rng_get(contextAlice->RNGContext, contextAlice->initiatorCachedSecretHash.rs1ID, 8);
johan's avatar
johan committed
503 504 505
	}

	if (contextAlice->cachedSecret.rs2!=NULL) {
johan's avatar
johan committed
506
		contextAlice->channelContext[0]->hmacFunction(contextAlice->cachedSecret.rs2, contextAlice->cachedSecret.rs2Length, (uint8_t *)"Initiator", 9, 8, contextAlice->initiatorCachedSecretHash.rs2ID);
johan's avatar
johan committed
507
	} else { /* we have no secret, generate a random */
508
		bctoolbox_rng_get(contextAlice->RNGContext, contextAlice->initiatorCachedSecretHash.rs2ID, 8);
johan's avatar
johan committed
509 510 511
	}

	if (contextAlice->cachedSecret.auxsecret!=NULL) {
512
		contextAlice->channelContext[0]->hmacFunction(contextAlice->cachedSecret.auxsecret, contextAlice->cachedSecret.auxsecretLength, contextAlice->channelContext[0]->selfH[3], 32, 8, contextAlice->channelContext[0]->initiatorAuxsecretID);
johan's avatar
johan committed
513
	} else { /* we have no secret, generate a random */
514
		bctoolbox_rng_get(contextAlice->RNGContext, contextAlice->channelContext[0]->initiatorAuxsecretID, 8);
johan's avatar
johan committed
515 516 517
	}

	if (contextAlice->cachedSecret.pbxsecret!=NULL) {
johan's avatar
johan committed
518
		contextAlice->channelContext[0]->hmacFunction(contextAlice->cachedSecret.pbxsecret, contextAlice->cachedSecret.pbxsecretLength, (uint8_t *)"Initiator", 9, 8, contextAlice->initiatorCachedSecretHash.pbxsecretID);
johan's avatar
johan committed
519
	} else { /* we have no secret, generate a random */
520
		bctoolbox_rng_get(contextAlice->RNGContext, contextAlice->initiatorCachedSecretHash.pbxsecretID, 8);
johan's avatar
johan committed
521 522 523
	}

	if (contextAlice->cachedSecret.rs1!=NULL) {
johan's avatar
johan committed
524
		contextAlice->channelContext[0]->hmacFunction(contextAlice->cachedSecret.rs1, contextAlice->cachedSecret.rs1Length, (uint8_t *)"Responder", 9, 8, contextAlice->responderCachedSecretHash.rs1ID);
johan's avatar
johan committed
525
	} else { /* we have no secret, generate a random */
526
		bctoolbox_rng_get(contextAlice->RNGContext, contextAlice->responderCachedSecretHash.rs1ID, 8);
johan's avatar
johan committed
527 528 529
	}

	if (contextAlice->cachedSecret.rs2!=NULL) {
johan's avatar
johan committed
530
		contextAlice->channelContext[0]->hmacFunction(contextAlice->cachedSecret.rs2, contextAlice->cachedSecret.rs2Length, (uint8_t *)"Responder", 9, 8, contextAlice->responderCachedSecretHash.rs2ID);
johan's avatar
johan committed
531
	} else { /* we have no secret, generate a random */
532
		bctoolbox_rng_get(contextAlice->RNGContext, contextAlice->responderCachedSecretHash.rs2ID, 8);
johan's avatar
johan committed
533 534 535
	}

	if (contextAlice->cachedSecret.auxsecret!=NULL) {
536
		contextAlice->channelContext[0]->hmacFunction(contextAlice->cachedSecret.auxsecret, contextAlice->cachedSecret.auxsecretLength, contextAlice->channelContext[0]->peerH[3], 32, 8, contextAlice->channelContext[0]->responderAuxsecretID);
johan's avatar
johan committed
537
	} else { /* we have no secret, generate a random */
538
		bctoolbox_rng_get(contextAlice->RNGContext, contextAlice->channelContext[0]->responderAuxsecretID, 8);
johan's avatar
johan committed
539 540 541
	}

	if (contextAlice->cachedSecret.pbxsecret!=NULL) {
johan's avatar
johan committed
542
		contextAlice->channelContext[0]->hmacFunction(contextAlice->cachedSecret.pbxsecret, contextAlice->cachedSecret.pbxsecretLength, (uint8_t *)"Responder", 9, 8, contextAlice->responderCachedSecretHash.pbxsecretID);
johan's avatar
johan committed
543
	} else { /* we have no secret, generate a random */
544
		bctoolbox_rng_get(contextAlice->RNGContext, contextAlice->responderCachedSecretHash.pbxsecretID, 8);
johan's avatar
johan committed
545 546 547 548 549
	}


	/* Bob hashes*/
	if (contextBob->cachedSecret.rs1!=NULL) {
johan's avatar
johan committed
550
		contextBob->channelContext[0]->hmacFunction(contextBob->cachedSecret.rs1, contextBob->cachedSecret.rs1Length, (uint8_t *)"Initiator", 9, 8, contextBob->initiatorCachedSecretHash.rs1ID);
johan's avatar
johan committed
551
	} else { /* we have no secret, generate a random */
552
		bctoolbox_rng_get(contextBob->RNGContext, contextBob->initiatorCachedSecretHash.rs1ID, 8);
johan's avatar
johan committed
553 554 555
	}

	if (contextBob->cachedSecret.rs2!=NULL) {
johan's avatar
johan committed
556
		contextBob->channelContext[0]->hmacFunction(contextBob->cachedSecret.rs2, contextBob->cachedSecret.rs2Length, (uint8_t *)"Initiator", 9, 8, contextBob->initiatorCachedSecretHash.rs2ID);
johan's avatar
johan committed
557
	} else { /* we have no secret, generate a random */
558
		bctoolbox_rng_get(contextBob->RNGContext, contextBob->initiatorCachedSecretHash.rs2ID, 8);
johan's avatar
johan committed
559 560 561
	}

	if (contextBob->cachedSecret.auxsecret!=NULL) {
562
		contextBob->channelContext[0]->hmacFunction(contextBob->cachedSecret.auxsecret, contextBob->cachedSecret.auxsecretLength, contextBob->channelContext[0]->selfH[3], 32, 8, contextBob->channelContext[0]->initiatorAuxsecretID);
johan's avatar
johan committed
563
	} else { /* we have no secret, generate a random */
564
		bctoolbox_rng_get(contextBob->RNGContext, contextBob->channelContext[0]->initiatorAuxsecretID, 8);
johan's avatar
johan committed
565 566 567
	}

	if (contextBob->cachedSecret.pbxsecret!=NULL) {
johan's avatar
johan committed
568
		contextBob->channelContext[0]->hmacFunction(contextBob->cachedSecret.pbxsecret, contextBob->cachedSecret.pbxsecretLength, (uint8_t *)"Initiator", 9, 8, contextBob->initiatorCachedSecretHash.pbxsecretID);
johan's avatar
johan committed
569
	} else { /* we have no secret, generate a random */
570
		bctoolbox_rng_get(contextBob->RNGContext, contextBob->initiatorCachedSecretHash.pbxsecretID, 8);
johan's avatar
johan committed
571 572 573
	}

	if (contextBob->cachedSecret.rs1!=NULL) {
johan's avatar
johan committed
574
		contextBob->channelContext[0]->hmacFunction(contextBob->cachedSecret.rs1, contextBob->cachedSecret.rs1Length, (uint8_t *)"Responder", 9, 8, contextBob->responderCachedSecretHash.rs1ID);
johan's avatar
johan committed
575
	} else { /* we have no secret, generate a random */
576
		bctoolbox_rng_get(contextBob->RNGContext, contextBob->responderCachedSecretHash.rs1ID, 8);
johan's avatar
johan committed
577 578 579
	}

	if (contextBob->cachedSecret.rs2!=NULL) {
johan's avatar
johan committed
580
		contextBob->channelContext[0]->hmacFunction(contextBob->cachedSecret.rs2, contextBob->cachedSecret.rs2Length, (uint8_t *)"Responder", 9, 8, contextBob->responderCachedSecretHash.rs2ID);
johan's avatar
johan committed
581
	} else { /* we have no secret, generate a random */
582
		bctoolbox_rng_get(contextBob->RNGContext, contextBob->responderCachedSecretHash.rs2ID, 8);
johan's avatar
johan committed
583 584 585
	}

	if (contextBob->cachedSecret.auxsecret!=NULL) {
586
		contextBob->channelContext[0]->hmacFunction(contextBob->cachedSecret.auxsecret, contextBob->cachedSecret.auxsecretLength, contextBob->channelContext[0]->peerH[3], 32, 8, contextBob->channelContext[0]->responderAuxsecretID);
johan's avatar
johan committed
587
	} else { /* we have no secret, generate a random */
588
		bctoolbox_rng_get(contextBob->RNGContext, contextBob->channelContext[0]->responderAuxsecretID, 8);
johan's avatar
johan committed
589 590 591
	}

	if (contextBob->cachedSecret.pbxsecret!=NULL) {
johan's avatar
johan committed
592
		contextBob->channelContext[0]->hmacFunction(contextBob->cachedSecret.pbxsecret, contextBob->cachedSecret.pbxsecretLength, (uint8_t *)"Responder", 9, 8, contextBob->responderCachedSecretHash.pbxsecretID);
johan's avatar
johan committed
593
	} else { /* we have no secret, generate a random */
594
		bctoolbox_rng_get(contextBob->RNGContext, contextBob->responderCachedSecretHash.pbxsecretID, 8);
johan's avatar
johan committed
595 596 597
	}

	/* dump alice's packet on both sides */
johan's avatar
johan committed
598
	bzrtp_message ("\nAlice original Packet is \n");
johan's avatar
johan committed
599
	packetDump(alice_Hello, 1);
johan's avatar
johan committed
600
	bzrtp_message ("\nBob's parsed Alice Packet is \n");
johan's avatar
johan committed
601 602 603
	packetDump(bob_HelloFromAlice, 0);

	/* Create the DHPart2 packet (that we then may change to DHPart1 if we ended to be the responder) */
604
	alice_selfDHPart = bzrtp_createZrtpPacket(contextAlice, contextAlice->channelContext[0], MSGTYPE_DHPART2, &retval);
johan's avatar
johan committed
605
	retval += bzrtp_packetBuild(contextAlice, contextAlice->channelContext[0], alice_selfDHPart, 0); /* we don't care now about sequence number as we just need to build the message to be able to insert a hash of it into the commit packet */
johan's avatar
johan committed
606
	if (retval == 0) { /* ok, insert it in context as we need it to build the commit packet */
johan's avatar
johan committed
607
		contextAlice->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID] = alice_selfDHPart;
johan's avatar
johan committed
608
	} else {
johan's avatar
johan committed
609
		bzrtp_message ("Alice building DHPart packet returns %x\n", retval);
johan's avatar
johan committed
610
	}
611
	bob_selfDHPart = bzrtp_createZrtpPacket(contextBob, contextBob->channelContext[0], MSGTYPE_DHPART2, &retval);
johan's avatar
johan committed
612
	retval +=bzrtp_packetBuild(contextBob, contextBob->channelContext[0], bob_selfDHPart, 0); /* we don't care now about sequence number as we just need to build the message to be able to insert a hash of it into the commit packet */
johan's avatar
johan committed
613
	if (retval == 0) { /* ok, insert it in context as we need it to build the commit packet */
johan's avatar
johan committed
614
		contextBob->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID] = bob_selfDHPart;
johan's avatar
johan committed
615
	} else {
johan's avatar
johan committed
616
		bzrtp_message ("Bob building DHPart packet returns %x\n", retval);
johan's avatar
johan committed
617
	}
johan's avatar
johan committed
618
	bzrtp_message("Alice DHPart packet:\n");
johan's avatar
johan committed
619
	packetDump(alice_selfDHPart,0);
johan's avatar
johan committed
620
	bzrtp_message("Bob DHPart packet:\n");
johan's avatar
johan committed
621 622 623
	packetDump(bob_selfDHPart,0);

	/* respond to HELLO packet with an HelloACK - 1 create packets */
johan's avatar
johan committed
624 625
	alice_HelloACK = bzrtp_createZrtpPacket(contextAlice, contextAlice->channelContext[0], MSGTYPE_HELLOACK, &retval);
	retval += bzrtp_packetBuild(contextAlice, contextAlice->channelContext[0], alice_HelloACK, contextAlice->channelContext[0]->selfSequenceNumber);
johan's avatar
johan committed
626
	if (retval == 0) {
johan's avatar
johan committed
627
		contextAlice->channelContext[0]->selfSequenceNumber++;
johan's avatar
johan committed
628
	} else {
johan's avatar
johan committed
629
		bzrtp_message("Alice building HelloACK return %x\n", retval);
johan's avatar
johan committed
630 631
	}

johan's avatar
johan committed
632 633
	bob_HelloACK = bzrtp_createZrtpPacket(contextBob, contextBob->channelContext[0], MSGTYPE_HELLOACK, &retval);
	retval += bzrtp_packetBuild(contextBob, contextBob->channelContext[0], bob_HelloACK, contextBob->channelContext[0]->selfSequenceNumber);
johan's avatar
johan committed
634
	if (retval == 0) {
johan's avatar
johan committed
635
		contextBob->channelContext[0]->selfSequenceNumber++;
johan's avatar
johan committed
636
	} else {
johan's avatar
johan committed
637
		bzrtp_message("Bob building HelloACK return %x\n", retval);
johan's avatar
johan committed
638 639 640
	}

	/* exchange the HelloACK */
johan's avatar
johan committed
641 642
	alice_HelloACKFromBob = bzrtp_packetCheck(bob_HelloACK->packetString, bob_HelloACK->messageLength+16, contextAlice->channelContext[0]->peerSequenceNumber, &retval);
	retval +=  bzrtp_packetParser(contextAlice, contextAlice->channelContext[0], bob_HelloACK->packetString, bob_HelloACK->messageLength+16, alice_HelloACKFromBob);
johan's avatar
johan committed
643
	bzrtp_message ("Alice parsing Hello ACK returns %x\n", retval);
johan's avatar
johan committed
644
	if (retval==0) {
johan's avatar
johan committed
645
		contextAlice->channelContext[0]->peerSequenceNumber = alice_HelloACKFromBob->sequenceNumber;
johan's avatar
johan committed
646 647
	}

johan's avatar
johan committed
648 649
	bob_HelloACKFromAlice = bzrtp_packetCheck(alice_HelloACK->packetString, alice_HelloACK->messageLength+16, contextBob->channelContext[0]->peerSequenceNumber, &retval);
	retval +=  bzrtp_packetParser(contextBob, contextBob->channelContext[0], alice_HelloACK->packetString, alice_HelloACK->messageLength+16, bob_HelloACKFromAlice);
johan's avatar
johan committed
650
	bzrtp_message ("Bob parsing Hello ACK returns %x\n", retval);
johan's avatar
johan committed
651
	if (retval==0) {
johan's avatar
johan committed
652
		contextBob->channelContext[0]->peerSequenceNumber = bob_HelloACKFromAlice->sequenceNumber;
johan's avatar
johan committed
653
	}
654 655 656 657
	bzrtp_freeZrtpPacket(alice_HelloACK);
	bzrtp_freeZrtpPacket(bob_HelloACK);
	bzrtp_freeZrtpPacket(alice_HelloACKFromBob);
	bzrtp_freeZrtpPacket(bob_HelloACKFromAlice);
johan's avatar
johan committed
658 659 660


	/* now build the commit message (both Alice and Bob will send it, then use the mechanism of rfc section 4.2 to determine who will be the initiator)*/
661
	alice_Commit = bzrtp_createZrtpPacket(contextAlice, contextAlice->channelContext[0], MSGTYPE_COMMIT, &retval);
johan's avatar
johan committed
662
	retval += bzrtp_packetBuild(contextAlice, contextAlice->channelContext[0], alice_Commit, contextAlice->channelContext[0]->selfSequenceNumber);
johan's avatar
johan committed
663
	if (retval == 0) {
johan's avatar
johan committed
664 665
		contextAlice->channelContext[0]->selfSequenceNumber++;
		contextAlice->channelContext[0]->selfPackets[COMMIT_MESSAGE_STORE_ID] = alice_Commit;
johan's avatar
johan committed
666
	}
johan's avatar
johan committed
667
	bzrtp_message("Alice building Commit return %x\n", retval);
668

669
	bob_Commit = bzrtp_createZrtpPacket(contextBob, contextBob->channelContext[0], MSGTYPE_COMMIT, &retval);
johan's avatar
johan committed
670
	retval += bzrtp_packetBuild(contextBob, contextBob->channelContext[0], bob_Commit, contextBob->channelContext[0]->selfSequenceNumber);
johan's avatar
johan committed
671
	if (retval == 0) {
johan's avatar
johan committed
672 673
		contextBob->channelContext[0]->selfSequenceNumber++;
		contextBob->channelContext[0]->selfPackets[COMMIT_MESSAGE_STORE_ID] = bob_Commit;
johan's avatar
johan committed
674
	}
johan's avatar
johan committed
675
	bzrtp_message("Bob building Commit return %x\n", retval);
johan's avatar
johan committed
676 677 678


	/* and exchange the commits */
679
	bob_CommitFromAlice = bzrtp_packetCheck(alice_Commit->packetString, alice_Commit->messageLength+16, contextBob->channelContext[0]->peerSequenceNumber, &retval);
johan's avatar
johan committed
680
	retval += bzrtp_packetParser(contextBob, contextBob->channelContext[0], alice_Commit->packetString, alice_Commit->messageLength+16, bob_CommitFromAlice);
johan's avatar
johan committed
681
	bzrtp_message ("Bob parsing Commit returns %x\n", retval);
johan's avatar
johan committed
682 683 684
	if (retval==0) {
		/* update context with the information found in the packet */
		bzrtpCommitMessage_t *bob_CommitFromAlice_message = (bzrtpCommitMessage_t *)bob_CommitFromAlice->messageData;
johan's avatar
johan committed
685 686 687
		contextBob->channelContext[0]->peerSequenceNumber = bob_CommitFromAlice->sequenceNumber;
		memcpy(contextBob->channelContext[0]->peerH[2], bob_CommitFromAlice_message->H2, 32);
		contextBob->channelContext[0]->peerPackets[COMMIT_MESSAGE_STORE_ID] = bob_CommitFromAlice;
johan's avatar
johan committed
688 689 690
	}
	packetDump(bob_CommitFromAlice, 0);

691
	alice_CommitFromBob = bzrtp_packetCheck(bob_Commit->packetString, bob_Commit->messageLength+16, contextAlice->channelContext[0]->peerSequenceNumber, &retval);
johan's avatar
johan committed
692
	retval += bzrtp_packetParser(contextAlice, contextAlice->channelContext[0], bob_Commit->packetString, bob_Commit->messageLength+16, alice_CommitFromBob);
johan's avatar
johan committed
693
	bzrtp_message ("Alice parsing Commit returns %x\n", retval);
johan's avatar
johan committed
694 695
	if (retval==0) {
		/* update context with the information found in the packet */
johan's avatar
johan committed
696 697 698
		contextAlice->channelContext[0]->peerSequenceNumber = alice_CommitFromBob->sequenceNumber;
		/* Alice will be the initiator (commit contention not implemented in this test) so just discard bob's commit */
		/*bzrtpCommirMessage_t *alice_CommitFromBob_message = (bzrtpCommitMessage_t *)alice_CommitFromBob->messageData;
699
		memcpy(contextAlice->channelContext[0]->peerH[2], alice_CommitFromBob_message->H2, 32);
johan's avatar
johan committed
700
		contextAlice->channelContext[0]->peerPackets[COMMIT_MESSAGE_STORE_ID] = alice_CommitFromBob;*/
johan's avatar
johan committed
701 702
	}
	packetDump(alice_CommitFromBob, 0);
703
	bzrtp_freeZrtpPacket(alice_CommitFromBob);
johan's avatar
johan committed
704 705 706 707

	/* Now determine who shall be the initiator : rfc section 4.2 */
	/* select the one with the lowest value of hvi */
	/* for test purpose, we will set Alice as the initiator */
johan's avatar
johan committed
708
	contextBob->channelContext[0]->role = RESPONDER;
johan's avatar
johan committed
709 710 711 712 713

	/* Bob (responder) shall update his selected algo list to match Alice selection */
	/* no need to do this here as we have the same selection */

	/* Bob is the responder, rebuild his DHPart packet to be responder and not initiator : */
johan's avatar
johan committed
714
	/* as responder, bob must also swap his aux shared secret between responder and initiator as they are computed using the H3 and not a constant string */
715 716 717
	memcpy(tmpBuffer, contextBob->channelContext[0]->initiatorAuxsecretID, 8);
	memcpy(contextBob->channelContext[0]->initiatorAuxsecretID, contextBob->channelContext[0]->responderAuxsecretID, 8);
	memcpy(contextBob->channelContext[0]->responderAuxsecretID, tmpBuffer, 8);
johan's avatar
johan committed
718

johan's avatar
johan committed
719
	contextBob->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->messageType = MSGTYPE_DHPART1; /* we are now part 1*/
720
	bob_DHPart1 = (bzrtpDHPartMessage_t *)contextBob->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->messageData;
johan's avatar
johan committed
721 722 723
	/* change the shared secret ID to the responder one (we set them by default to the initiator's one) */
	memcpy(bob_DHPart1->rs1ID, contextBob->responderCachedSecretHash.rs1ID, 8);
	memcpy(bob_DHPart1->rs2ID, contextBob->responderCachedSecretHash.rs2ID, 8);
724
	memcpy(bob_DHPart1->auxsecretID, contextBob->channelContext[0]->responderAuxsecretID, 8);
johan's avatar
johan committed
725 726
	memcpy(bob_DHPart1->pbxsecretID, contextBob->responderCachedSecretHash.pbxsecretID, 8);

johan's avatar
johan committed
727
	retval +=bzrtp_packetBuild(contextBob, contextBob->channelContext[0], contextBob->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID],contextBob->channelContext[0]->selfSequenceNumber);
johan's avatar
johan committed
728
	if (retval == 0) {
johan's avatar
johan committed
729
		contextBob->channelContext[0]->selfSequenceNumber++;
johan's avatar
johan committed
730
	}
johan's avatar
johan committed
731
	bzrtp_message("Bob building DHPart1 return %x\n", retval);
johan's avatar
johan committed
732 733 734


	/* Alice parse bob's DHPart1 message */
735
	alice_DHPart1FromBob = bzrtp_packetCheck(contextBob->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->packetString, contextBob->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->messageLength+16, contextAlice->channelContext[0]->peerSequenceNumber, &retval);
johan's avatar
johan committed
736
	retval += bzrtp_packetParser(contextAlice, contextAlice->channelContext[0], contextBob->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->packetString, contextBob->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->messageLength+16, alice_DHPart1FromBob);
johan's avatar
johan committed
737
	bzrtp_message ("Alice parsing DHPart1 returns %x\n", retval);
johan's avatar
johan committed
738 739
	if (retval==0) {
		/* update context with the information found in the packet */
johan's avatar
johan committed
740
		contextAlice->channelContext[0]->peerSequenceNumber = alice_DHPart1FromBob->sequenceNumber;
johan's avatar
johan committed
741
		alice_DHPart1FromBob_message = (bzrtpDHPartMessage_t *)alice_DHPart1FromBob->messageData;
johan's avatar
johan committed
742 743
		memcpy(contextAlice->channelContext[0]->peerH[1], alice_DHPart1FromBob_message->H1, 32);
		contextAlice->channelContext[0]->peerPackets[DHPART_MESSAGE_STORE_ID] = alice_DHPart1FromBob;
johan's avatar
johan committed
744 745 746 747 748 749
	}
	packetDump(alice_DHPart1FromBob, 1);

	/* Now Alice may check which shared secret she expected and if they are valid in bob's DHPart1 */
	if (contextAlice->cachedSecret.rs1!=NULL) {
		if (memcmp(contextAlice->responderCachedSecretHash.rs1ID, alice_DHPart1FromBob_message->rs1ID,8) != 0) {
johan's avatar
johan committed
750
			bzrtp_message ("Alice found that requested shared secret rs1 ID differs!\n");
johan's avatar
johan committed
751
		} else {
johan's avatar
johan committed
752
			bzrtp_message("Alice validate rs1ID from bob DHPart1\n");
johan's avatar
johan committed
753 754 755 756
		}
	}
	if (contextAlice->cachedSecret.rs2!=NULL) {
		if (memcmp(contextAlice->responderCachedSecretHash.rs2ID, alice_DHPart1FromBob_message->rs2ID,8) != 0) {
johan's avatar
johan committed
757
			bzrtp_message ("Alice found that requested shared secret rs2 ID differs!\n");
johan's avatar
johan committed
758
		} else {
johan's avatar
johan committed
759
			bzrtp_message("Alice validate rs2ID from bob DHPart1\n");
johan's avatar
johan committed
760 761 762
		}
	}
	if (contextAlice->cachedSecret.auxsecret!=NULL) {
763
		if (memcmp(contextAlice->channelContext[0]->responderAuxsecretID, alice_DHPart1FromBob_message->auxsecretID,8) != 0) {
johan's avatar
johan committed
764
			bzrtp_message ("Alice found that requested shared secret aux secret ID differs!\n");
johan's avatar
johan committed
765
		} else {
johan's avatar
johan committed
766
			bzrtp_message("Alice validate aux secret ID from bob DHPart1\n");
johan's avatar
johan committed
767 768 769 770
		}
	}
	if (contextAlice->cachedSecret.pbxsecret!=NULL) {
		if (memcmp(contextAlice->responderCachedSecretHash.pbxsecretID, alice_DHPart1FromBob_message->pbxsecretID,8) != 0) {
johan's avatar
johan committed
771
			bzrtp_message ("Alice found that requested shared secret pbx secret ID differs!\n");
johan's avatar
johan committed
772
		} else {
johan's avatar
johan committed
773
			bzrtp_message("Alice validate pbxsecretID from bob DHPart1\n");
johan's avatar
johan committed
774 775 776 777 778
		}
	}

	/* Now Alice shall check that the PV from bob is not 1 or Prime-1 TODO*/
	/* Compute the shared DH secret */
779 780
	contextAlice->DHMContext->peer = (uint8_t *)malloc(contextAlice->channelContext[0]->keyAgreementLength*sizeof(uint8_t));
	memcpy (contextAlice->DHMContext->peer, alice_DHPart1FromBob_message->pv, contextAlice->channelContext[0]->keyAgreementLength);
781
	bctoolbox_DHMComputeSecret(contextAlice->DHMContext, (int (*)(void *, uint8_t *, size_t))bctoolbox_rng_get, (void *)contextAlice->RNGContext);
johan's avatar
johan committed
782 783

	/* So Alice send bob her DHPart2 message which is already prepared and stored (we just need to update the sequence number) */
johan's avatar
johan committed
784 785
	bzrtp_packetUpdateSequenceNumber(contextAlice->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID], contextAlice->channelContext[0]->selfSequenceNumber);
	contextAlice->channelContext[0]->selfSequenceNumber++;
johan's avatar
johan committed
786 787

	/* Bob parse Alice's DHPart2 message */
788
	bob_DHPart2FromAlice = bzrtp_packetCheck(contextAlice->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->packetString, contextAlice->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->messageLength+16, contextBob->channelContext[0]->peerSequenceNumber, &retval);
johan's avatar
johan committed
789
	bzrtp_message ("Bob checking DHPart2 returns %x\n", retval);
johan's avatar
johan committed
790
	retval += bzrtp_packetParser(contextBob, contextBob->channelContext[0], contextAlice->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->packetString, contextAlice->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->messageLength+16, bob_DHPart2FromAlice);
johan's avatar
johan committed
791
	bzrtp_message ("Bob parsing DHPart2 returns %x\n", retval);
johan's avatar
johan committed
792 793
	if (retval==0) {
		/* update context with the information found in the packet */
johan's avatar
johan committed
794
		contextBob->channelContext[0]->peerSequenceNumber = bob_DHPart2FromAlice->sequenceNumber;
johan's avatar
johan committed
795
		bob_DHPart2FromAlice_message = (bzrtpDHPartMessage_t *)bob_DHPart2FromAlice->messageData;
johan's avatar
johan committed
796 797
		memcpy(contextBob->channelContext[0]->peerH[1], bob_DHPart2FromAlice_message->H1, 32);
		contextBob->channelContext[0]->peerPackets[DHPART_MESSAGE_STORE_ID] = bob_DHPart2FromAlice;
johan's avatar
johan committed
798 799 800 801 802 803
	}
	packetDump(bob_DHPart2FromAlice, 0);

	/* Now Bob may check which shared secret she expected and if they are valid in bob's DHPart1 */
	if (contextBob->cachedSecret.rs1!=NULL) {
		if (memcmp(contextBob->initiatorCachedSecretHash.rs1ID, bob_DHPart2FromAlice_message->rs1ID,8) != 0) {
johan's avatar
johan committed
804
			bzrtp_message ("Bob found that requested shared secret rs1 ID differs!\n");
johan's avatar
johan committed
805
		} else {
johan's avatar
johan committed
806
			bzrtp_message("Bob validate rs1ID from Alice DHPart2\n");
johan's avatar
johan committed
807 808 809 810
		}
	}
	if (contextBob->cachedSecret.rs2!=NULL) {
		if (memcmp(contextBob->initiatorCachedSecretHash.rs2ID, bob_DHPart2FromAlice_message->rs2ID,8) != 0) {
johan's avatar
johan committed
811
			bzrtp_message ("Bob found that requested shared secret rs2 ID differs!\n");
johan's avatar
johan committed
812
		} else {
johan's avatar
johan committed
813
			bzrtp_message("Bob validate rs2ID from Alice DHPart2\n");
johan's avatar
johan committed
814 815 816
		}
	}
	if (contextBob->cachedSecret.auxsecret!=NULL) {
817
		if (memcmp(contextBob->channelContext[0]->initiatorAuxsecretID, bob_DHPart2FromAlice_message->auxsecretID,8) != 0) {
johan's avatar
johan committed
818
			bzrtp_message ("Bob found that requested shared secret aux secret ID differs!\n");
johan's avatar
johan committed
819
		} else {
johan's avatar
johan committed
820
			bzrtp_message("Bob validate aux secret ID from Alice DHPart2\n");
johan's avatar
johan committed
821 822 823 824
		}
	}
	if (contextBob->cachedSecret.pbxsecret!=NULL) {
		if (memcmp(contextBob->initiatorCachedSecretHash.pbxsecretID, bob_DHPart2FromAlice_message->pbxsecretID,8) != 0) {
johan's avatar
johan committed
825
			bzrtp_message ("Bob found that requested shared secret pbx secret ID differs!\n");
johan's avatar
johan committed
826
		} else {
johan's avatar
johan committed
827
			bzrtp_message("Bob validate pbxsecretID from Alice DHPart2\n");
johan's avatar
johan committed
828 829 830 831 832
		}
	}

	/* Now Bob shall check that the PV from Alice is not 1 or Prime-1 TODO*/
	/* Compute the shared DH secret */
833 834
	contextBob->DHMContext->peer = (uint8_t *)malloc(contextBob->channelContext[0]->keyAgreementLength*sizeof(uint8_t));
	memcpy (contextBob->DHMContext->peer, bob_DHPart2FromAlice_message->pv, contextBob->channelContext[0]->keyAgreementLength);
835
	bctoolbox_DHMComputeSecret(contextBob->DHMContext, (int (*)(void *, uint8_t *, size_t))bctoolbox_rng_get, (void *)contextAlice->RNGContext);
johan's avatar
johan committed
836 837 838


	/* JUST FOR TEST: check that the generated secrets are the same */
839
	secretLength = bob_DHPart2FromAlice->messageLength-84; /* length of generated secret is the same than public value */
johan's avatar
johan committed
840
	if (memcmp(contextBob->DHMContext->key, contextAlice->DHMContext->key, secretLength)==0) {
johan's avatar
johan committed
841
		bzrtp_message("Secret Key correctly exchanged \n");
johan's avatar
johan committed
842 843 844
		CU_PASS("Secret Key exchange OK");
	} else {
		CU_FAIL("Secret Key exchange failed");
johan's avatar
johan committed
845
		bzrtp_message("ERROR : secretKey exchange failed!!\n");
johan's avatar
johan committed
846 847
	}

848
	/* now compute the total_hash as in rfc section 4.4.1.4
johan's avatar
johan committed
849 850
	 * total_hash = hash(Hello of responder || Commit || DHPart1 || DHPart2)
	 */
851 852
	totalHashDataLength = bob_Hello->messageLength + alice_Commit->messageLength + contextBob->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->messageLength + alice_selfDHPart->messageLength;
	dataToHash = (uint8_t *)malloc(totalHashDataLength*sizeof(uint8_t));
johan's avatar
johan committed
853
	/* get all data from Alice */
johan's avatar
johan committed
854 855 856 857 858 859 860
	memcpy(dataToHash, contextAlice->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID]->packetString+ZRTP_PACKET_HEADER_LENGTH, contextAlice->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID]->messageLength);
	hashDataIndex += contextAlice->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID]->messageLength;
	memcpy(dataToHash+hashDataIndex, contextAlice->channelContext[0]->selfPackets[COMMIT_MESSAGE_STORE_ID]->packetString+ZRTP_PACKET_HEADER_LENGTH, contextAlice->channelContext[0]->selfPackets[COMMIT_MESSAGE_STORE_ID]->messageLength);
	hashDataIndex += contextAlice->channelContext[0]->selfPackets[COMMIT_MESSAGE_STORE_ID]->messageLength;
	memcpy(dataToHash+hashDataIndex, contextAlice->channelContext[0]->peerPackets[DHPART_MESSAGE_STORE_ID]->packetString+ZRTP_PACKET_HEADER_LENGTH, contextAlice->channelContext[0]->peerPackets[DHPART_MESSAGE_STORE_ID]->messageLength);
	hashDataIndex += contextAlice->channelContext[0]->peerPackets[DHPART_MESSAGE_STORE_ID]->messageLength;
	memcpy(dataToHash+hashDataIndex, contextAlice->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->packetString+ZRTP_PACKET_HEADER_LENGTH, contextAlice->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->messageLength);
johan's avatar
johan committed
861

johan's avatar
johan committed
862
	contextAlice->channelContext[0]->hashFunction(dataToHash, totalHashDataLength, 32, alice_totalHash);
johan's avatar
johan committed
863 864 865

	/* get all data from Bob */
	hashDataIndex = 0;
johan's avatar
johan committed
866 867 868 869 870 871 872
	memcpy(dataToHash, contextBob->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID]->packetString+ZRTP_PACKET_HEADER_LENGTH, contextBob->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID]->messageLength);
	hashDataIndex += contextBob->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID]->messageLength;
	memcpy(dataToHash+hashDataIndex, contextBob->channelContext[0]->peerPackets[COMMIT_MESSAGE_STORE_ID]->packetString+ZRTP_PACKET_HEADER_LENGTH, contextBob->channelContext[0]->peerPackets[COMMIT_MESSAGE_STORE_ID]->messageLength);
	hashDataIndex += contextBob->channelContext[0]->peerPackets[COMMIT_MESSAGE_STORE_ID]->messageLength;
	memcpy(dataToHash+hashDataIndex, contextBob->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->packetString+ZRTP_PACKET_HEADER_LENGTH, contextBob->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->messageLength);
	hashDataIndex += contextBob->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID]->messageLength;
	memcpy(dataToHash+hashDataIndex, contextBob->channelContext[0]->peerPackets[DHPART_MESSAGE_STORE_ID]->packetString+ZRTP_PACKET_HEADER_LENGTH, contextBob->channelContext[0]->peerPackets[DHPART_MESSAGE_STORE_ID]->messageLength);
johan's avatar
johan committed
873

johan's avatar
johan committed
874
	contextBob->channelContext[0]->hashFunction(dataToHash, totalHashDataLength, 32, bob_totalHash);
johan's avatar
johan committed
875
	if (memcmp(bob_totalHash, alice_totalHash, 32) == 0) {
johan's avatar
johan committed
876
		bzrtp_message("Got the same total hash\n");
johan's avatar
johan committed
877 878
		CU_PASS("Total Hash match");
	} else {
johan's avatar
johan committed
879
		bzrtp_message("AARGG!! total hash mismatch");
johan's avatar
johan committed
880 881 882
		CU_FAIL("Total Hash mismatch");
	}

883
	/* now compute s0 and KDF_context as in rfc section 4.4.1.4
johan's avatar
johan committed
884 885 886 887
		s0 = hash(counter || DHResult || "ZRTP-HMAC-KDF" || ZIDi || ZIDr || total_hash || len(s1) || s1 || len(s2) || s2 || len(s3) || s3)
		counter is a fixed 32 bits integer in big endian set to 1 : 0x00000001
	*/
	free(dataToHash);
johan's avatar
johan committed
888 889 890 891 892
	contextAlice->channelContext[0]->KDFContextLength = 24+32;/* actual depends on selected hash length*/
	contextAlice->channelContext[0]->KDFContext = (uint8_t *)malloc(contextAlice->channelContext[0]->KDFContextLength*sizeof(uint8_t));
	memcpy(contextAlice->channelContext[0]->KDFContext, contextAlice->selfZID, 12); /* ZIDi*/
	memcpy(contextAlice->channelContext[0]->KDFContext+12, contextAlice->peerZID, 12); /* ZIDr */
	memcpy(contextAlice->channelContext[0]->KDFContext+24, alice_totalHash, 32); /* total Hash*/
johan's avatar
johan committed
893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909

	/* get s1 from rs1 or rs2 */
	if (contextAlice->cachedSecret.rs1 != NULL) { /* if there is a s1 (already validated when received the DHpacket) */
		s1 = contextAlice->cachedSecret.rs1;
		s1Length = contextAlice->cachedSecret.rs1Length;
	} else if (contextAlice->cachedSecret.rs2 != NULL) { /* otherwise if there is a s2 (already validated when received the DHpacket) */
		s1 = contextAlice->cachedSecret.rs2;
		s1Length = contextAlice->cachedSecret.rs2Length;
	}

	/* s2 is the auxsecret */
	s2 = contextAlice->cachedSecret.auxsecret; /* this may be null if no match or no aux secret where found */
	s2Length = contextAlice->cachedSecret.auxsecretLength; /* this may be 0 if no match or no aux secret where found */

	/* s3 is the pbxsecret */
	s3 = contextAlice->cachedSecret.pbxsecret; /* this may be null if no match or no pbx secret where found */
	s3Length = contextAlice->cachedSecret.pbxsecretLength; /* this may be 0 if no match or no pbx secret where found */
910

johan's avatar
johan committed
911 912 913 914 915 916 917 918
	totalHashDataLength = 4+secretLength+13/*ZRTP-HMAC-KDF string*/ + 12 + 12 + 32 + 4 +s1Length + 4 +s2Length + 4 + s3Length; /* secret length was computed before as the length of DH secret data */

	dataToHash = (uint8_t *)malloc(totalHashDataLength*sizeof(uint8_t));
	dataToHash[0] = 0x00;
	dataToHash[1] = 0x00;
	dataToHash[2] = 0x00;
	dataToHash[3] = 0x01;
	hashDataIndex = 4;
919

johan's avatar
johan committed
920 921 922 923
	memcpy(dataToHash+hashDataIndex, contextAlice->DHMContext->key, secretLength);
	hashDataIndex += secretLength;
	memcpy(dataToHash+hashDataIndex, "ZRTP-HMAC-KDF", 13);
	hashDataIndex += 13;
johan's avatar
johan committed
924
	memcpy(dataToHash+hashDataIndex, contextAlice->channelContext[0]->KDFContext, contextAlice->channelContext[0]->KDFContextLength);
johan's avatar
johan committed
925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953
	hashDataIndex += 56;

	dataToHash[hashDataIndex++] = (uint8_t)((s1Length>>24)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)((s1Length>>16)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)((s1Length>>8)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)(s1Length&0xFF);
	if (s1!=NULL) {
		memcpy(dataToHash+hashDataIndex, s1, s1Length);
		hashDataIndex += s1Length;
	}

	dataToHash[hashDataIndex++] = (uint8_t)((s2Length>>24)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)((s2Length>>16)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)((s2Length>>8)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)(s2Length&0xFF);
	if (s2!=NULL) {
		memcpy(dataToHash+hashDataIndex, s2, s2Length);
		hashDataIndex += s2Length;
	}

	dataToHash[hashDataIndex++] = (uint8_t)((s3Length>>24)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)((s3Length>>16)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)((s3Length>>8)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)(s3Length&0xFF);
	if (s3!=NULL) {
		memcpy(dataToHash+hashDataIndex, s3, s3Length);
		hashDataIndex += s3Length;
	}

johan's avatar
johan committed
954 955
	contextAlice->channelContext[0]->s0 = (uint8_t *)malloc(32*sizeof(uint8_t));
	contextAlice->channelContext[0]->hashFunction(dataToHash, totalHashDataLength, 32, contextAlice->channelContext[0]->s0);
johan's avatar
johan committed
956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983

	/* destroy all cached keys in context */
	if (contextAlice->cachedSecret.rs1!=NULL) {
		bzrtp_DestroyKey(contextAlice->cachedSecret.rs1, contextAlice->cachedSecret.rs1Length, contextAlice->RNGContext);
		free(contextAlice->cachedSecret.rs1);
		contextAlice->cachedSecret.rs1 = NULL;
	}
	if (contextAlice->cachedSecret.rs2!=NULL) {
		bzrtp_DestroyKey(contextAlice->cachedSecret.rs2, contextAlice->cachedSecret.rs2Length, contextAlice->RNGContext);
		free(contextAlice->cachedSecret.rs2);
		contextAlice->cachedSecret.rs2 = NULL;
	}
	if (contextAlice->cachedSecret.auxsecret!=NULL) {
		bzrtp_DestroyKey(contextAlice->cachedSecret.auxsecret, contextAlice->cachedSecret.auxsecretLength, contextAlice->RNGContext);
		free(contextAlice->cachedSecret.auxsecret);
		contextAlice->cachedSecret.auxsecret = NULL;
	}
	if (contextAlice->cachedSecret.pbxsecret!=NULL) {
		bzrtp_DestroyKey(contextAlice->cachedSecret.pbxsecret, contextAlice->cachedSecret.pbxsecretLength, contextAlice->RNGContext);
		free(contextAlice->cachedSecret.pbxsecret);
		contextAlice->cachedSecret.pbxsecret = NULL;
	}

	/*** Do the same for bob ***/
	/* get s1 from rs1 or rs2 */
	s1=NULL;
	s2=NULL;
	s3=NULL;
johan's avatar
johan committed
984 985 986 987 988
	contextBob->channelContext[0]->KDFContextLength = 24+32;/* actual depends on selected hash length*/
	contextBob->channelContext[0]->KDFContext = (uint8_t *)malloc(contextBob->channelContext[0]->KDFContextLength*sizeof(uint8_t));
	memcpy(contextBob->channelContext[0]->KDFContext, contextBob->peerZID, 12); /* ZIDi*/
	memcpy(contextBob->channelContext[0]->KDFContext+12, contextBob->selfZID, 12); /* ZIDr */
	memcpy(contextBob->channelContext[0]->KDFContext+24, bob_totalHash, 32); /* total Hash*/
johan's avatar
johan committed
989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012

	if (contextBob->cachedSecret.rs1 != NULL) { /* if there is a s1 (already validated when received the DHpacket) */
		s1 = contextBob->cachedSecret.rs1;
		s1Length = contextBob->cachedSecret.rs1Length;
	} else if (contextBob->cachedSecret.rs2 != NULL) { /* otherwise if there is a s2 (already validated when received the DHpacket) */
		s1 = contextBob->cachedSecret.rs2;
		s1Length = contextBob->cachedSecret.rs2Length;
	}

	/* s2 is the auxsecret */
	s2 = contextBob->cachedSecret.auxsecret; /* this may be null if no match or no aux secret where found */
	s2Length = contextBob->cachedSecret.auxsecretLength; /* this may be 0 if no match or no aux secret where found */

	/* s3 is the pbxsecret */
	s3 = contextBob->cachedSecret.pbxsecret; /* this may be null if no match or no pbx secret where found */
	s3Length = contextBob->cachedSecret.pbxsecretLength; /* this may be 0 if no match or no pbx secret where found */

	free(dataToHash);
	dataToHash = (uint8_t *)malloc(totalHashDataLength*sizeof(uint8_t));
	dataToHash[0] = 0x00;
	dataToHash[1] = 0x00;
	dataToHash[2] = 0x00;
	dataToHash[3] = 0x01;
	hashDataIndex = 4;
1013

johan's avatar
johan committed
1014 1015 1016 1017
	memcpy(dataToHash+hashDataIndex, contextBob->DHMContext->key, secretLength);
	hashDataIndex += secretLength;
	memcpy(dataToHash+hashDataIndex, "ZRTP-HMAC-KDF", 13);
	hashDataIndex += 13;
johan's avatar
johan committed
1018
	memcpy(dataToHash+hashDataIndex, contextBob->channelContext[0]->KDFContext, contextBob->channelContext[0]->KDFContextLength);
johan's avatar
johan committed
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
	hashDataIndex += 56;

	dataToHash[hashDataIndex++] = (uint8_t)((s1Length>>24)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)((s1Length>>16)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)((s1Length>>8)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)(s1Length&0xFF);
	if (s1!=NULL) {
		memcpy(dataToHash+hashDataIndex, s1, s1Length);
		hashDataIndex += s1Length;
	}

	dataToHash[hashDataIndex++] = (uint8_t)((s2Length>>24)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)((s2Length>>16)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)((s2Length>>8)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)(s2Length&0xFF);
	if (s2!=NULL) {
		memcpy(dataToHash+hashDataIndex, s2, s2Length);
		hashDataIndex += s2Length;
	}

	dataToHash[hashDataIndex++] = (uint8_t)((s3Length>>24)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)((s3Length>>16)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)((s3Length>>8)&0xFF);
	dataToHash[hashDataIndex++] = (uint8_t)(s3Length&0xFF);
	if (s3!=NULL) {
		memcpy(dataToHash+hashDataIndex, s3, s3Length);
		hashDataIndex += s3Length;
	}

johan's avatar
johan committed
1048 1049
	contextBob->channelContext[0]->s0 = (uint8_t *)malloc(32*sizeof(uint8_t));
	contextBob->channelContext[0]->hashFunction(dataToHash, totalHashDataLength, 32, contextBob->channelContext[0]->s0);
1050

1051
	free(dataToHash);
johan's avatar
johan committed
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076

	/* destroy all cached keys in context */
	if (contextBob->cachedSecret.rs1!=NULL) {
		bzrtp_DestroyKey(contextBob->cachedSecret.rs1, contextBob->cachedSecret.rs1Length, contextBob->RNGContext);
		free(contextBob->cachedSecret.rs1);
		contextBob->cachedSecret.rs1 = NULL;
	}
	if (contextBob->cachedSecret.rs2!=NULL) {
		bzrtp_DestroyKey(contextBob->cachedSecret.rs2, contextBob->cachedSecret.rs2Length, contextBob->RNGContext);
		free(contextBob->cachedSecret.rs2);
		contextBob->cachedSecret.rs2 = NULL;
	}
	if (contextBob->cachedSecret.auxsecret!=NULL) {
		bzrtp_DestroyKey(contextBob->cachedSecret.auxsecret, contextBob->cachedSecret.auxsecretLength, contextBob->RNGContext);
		free(contextBob->cachedSecret.auxsecret);
		contextBob->cachedSecret.auxsecret = NULL;
	}
	if (contextBob->cachedSecret.pbxsecret!=NULL) {
		bzrtp_DestroyKey(contextBob->cachedSecret.pbxsecret, contextBob->cachedSecret.pbxsecretLength, contextBob->RNGContext);
		free(contextBob->cachedSecret.pbxsecret);
		contextBob->cachedSecret.pbxsecret = NULL;
	}


	/* DEBUG compare s0 */
johan's avatar
johan committed
1077
	if (memcmp(contextBob->channelContext[0]->s0, contextAlice->channelContext[0]->s0, 32)==0) {
johan's avatar
johan committed
1078
		bzrtp_message("Got the same s0\n");
johan's avatar
johan committed
1079 1080
		CU_PASS("s0 match");</