Commit 52a5f697 authored by johan's avatar johan

Add support for ECDH25519 and ECDH448 when available in bctoolbox

parent 8475e143
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
@author Johan Pascal @author Johan Pascal
@copyright Copyright (C) 2014 Belledonne Communications, Grenoble, France @copyright Copyright (C) 2017 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
...@@ -76,13 +76,15 @@ ...@@ -76,13 +76,15 @@
* as it is used to easily sort them from faster(DH2k) to slower(EC52) * as it is used to easily sort them from faster(DH2k) to slower(EC52)
*/ */
#define ZRTP_KEYAGREEMENT_DH2k 0x41 #define ZRTP_KEYAGREEMENT_DH2k 0x41
#define ZRTP_KEYAGREEMENT_EC25 0x42 #define ZRTP_KEYAGREEMENT_X255 0x42
#define ZRTP_KEYAGREEMENT_DH3k 0x43 #define ZRTP_KEYAGREEMENT_EC25 0x43
#define ZRTP_KEYAGREEMENT_EC38 0x44 #define ZRTP_KEYAGREEMENT_X448 0x44
#define ZRTP_KEYAGREEMENT_EC52 0x45 #define ZRTP_KEYAGREEMENT_DH3k 0x45
#define ZRTP_KEYAGREEMENT_EC38 0x46
#define ZRTP_KEYAGREEMENT_Prsh 0x46 #define ZRTP_KEYAGREEMENT_EC52 0x47
#define ZRTP_KEYAGREEMENT_Mult 0x47
#define ZRTP_KEYAGREEMENT_Prsh 0x4e
#define ZRTP_KEYAGREEMENT_Mult 0x4f
#define ZRTP_SAS_B32 0x51 #define ZRTP_SAS_B32 0x51
#define ZRTP_SAS_B256 0x52 #define ZRTP_SAS_B256 0x52
......
...@@ -160,15 +160,15 @@ struct bzrtpChannelContext_struct { ...@@ -160,15 +160,15 @@ struct bzrtpChannelContext_struct {
uint16_t selfSequenceNumber; /**< Sequence number of the next packet to be sent */ uint16_t selfSequenceNumber; /**< Sequence number of the next packet to be sent */
uint16_t peerSequenceNumber; /**< Sequence number of the last valid received packet */ uint16_t peerSequenceNumber; /**< Sequence number of the last valid received packet */
/* algorithm agreed after Hello message exchange(use mapping define in cryptoWrapper.h) and the function pointer to use them */ /* algorithm agreed after Hello message exchange(use mapping define in cryptoUtils.h) and the function pointer to use them */
uint8_t hashAlgo; /**< hash algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoWrapper.h */ uint8_t hashAlgo; /**< hash algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoUtils.h */
uint8_t hashLength; /**< the length in bytes of a hash generated with the agreed hash algo */ uint8_t hashLength; /**< the length in bytes of a hash generated with the agreed hash algo */
uint8_t cipherAlgo; /**< cipher algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoWrapper.h */ uint8_t cipherAlgo; /**< cipher algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoUtils.h */
uint8_t cipherKeyLength; /**< the length in bytes of the key needed by the agreed cipher block algo */ uint8_t cipherKeyLength; /**< the length in bytes of the key needed by the agreed cipher block algo */
uint8_t authTagAlgo; /**< srtp authentication tag algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoWrapper.h */ uint8_t authTagAlgo; /**< srtp authentication tag algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoUtils.h */
uint8_t keyAgreementAlgo; /**< key agreement algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoWrapper.h */ uint8_t keyAgreementAlgo; /**< key agreement algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoUtils.h */
uint16_t keyAgreementLength; /**< the length in byte of the secret generated by the agreed key exchange algo */ uint16_t keyAgreementLength; /**< the length in byte of the secret generated by the agreed key exchange algo */
uint8_t sasAlgo; /**< sas rendering algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoWrapper.h */ uint8_t sasAlgo; /**< sas rendering algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoUtils.h */
uint8_t sasLength; /**< length of the SAS depends on the algorithm agreed */ uint8_t sasLength; /**< length of the SAS depends on the algorithm agreed */
/* function pointer to the agreed algorithms - Note, key agreement manage directly this selection so it is not set here */ /* function pointer to the agreed algorithms - Note, key agreement manage directly this selection so it is not set here */
...@@ -204,7 +204,8 @@ struct bzrtpChannelContext_struct { ...@@ -204,7 +204,8 @@ struct bzrtpChannelContext_struct {
struct bzrtpContext_struct { struct bzrtpContext_struct {
/* contexts */ /* contexts */
bctbx_rng_context_t *RNGContext; /**< context for random number generation */ bctbx_rng_context_t *RNGContext; /**< context for random number generation */
bctbx_DHMContext_t *DHMContext; /**< context for the Diffie-Hellman-Merkle operations. Only one DHM computation may be done during a call, so this belongs to the general context and not the channel one */ void *keyAgreementContext; /**< context for the key agreement operations. Only one key agreement computation may be done during a call, so this belongs to the general context and not the channel one */
uint8_t keyAgreementAlgo; /**< key agreement algorithm agreed on the first channel, the one performing key exchange, stored using integer mapping defined in cryptoUtils.h, */
/* flags */ /* flags */
uint8_t isInitialised; /**< this flag is set once the context was initialised : self ZID retrieved from cache or generated, used to unlock the creation of addtional channels */ uint8_t isInitialised; /**< this flag is set once the context was initialised : self ZID retrieved from cache or generated, used to unlock the creation of addtional channels */
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
@author Johan Pascal @author Johan Pascal
@copyright Copyright (C) 2014 Belledonne Communications, Grenoble, France @copyright Copyright (C) 2017 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
...@@ -56,7 +56,8 @@ bzrtpContext_t *bzrtp_createBzrtpContext(void) { ...@@ -56,7 +56,8 @@ bzrtpContext_t *bzrtp_createBzrtpContext(void) {
/* start the random number generator */ /* start the random number generator */
context->RNGContext = bctbx_rng_context_new(); /* TODO: give a seed for the RNG? */ context->RNGContext = bctbx_rng_context_new(); /* TODO: give a seed for the RNG? */
/* set the DHM context to NULL, it will be created if needed when creating a DHPart packet */ /* set the DHM context to NULL, it will be created if needed when creating a DHPart packet */
context->DHMContext = NULL; context->keyAgreementContext = NULL;
context->keyAgreementAlgo = ZRTP_UNSET_ALGO;
/* set flags */ /* set flags */
context->isSecure = 0; /* start unsecure */ context->isSecure = 0; /* start unsecure */
...@@ -196,10 +197,16 @@ int bzrtp_destroyBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC) { ...@@ -196,10 +197,16 @@ int bzrtp_destroyBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC) {
/* We have no more channel, destroy the zrtp context */ /* We have no more channel, destroy the zrtp context */
/* DHM context shall already been destroyed after s0 computation, but just in case */ /* key agreement context shall already been destroyed after s0 computation, but just in case */
if (context->DHMContext != NULL) { if (context->keyAgreementContext != NULL) {
bctbx_DestroyDHMContext(context->DHMContext); if (context->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X255 || context->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X448) {
context->DHMContext = NULL; bctbx_DestroyECDHContext((bctbx_ECDHContext_t *)context->keyAgreementContext);
}
if (context->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH2k || context->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH3k) {
bctbx_DestroyDHMContext((bctbx_DHMContext_t *)context->keyAgreementContext);
}
context->keyAgreementContext = NULL;
context->keyAgreementAlgo = ZRTP_UNSET_ALGO;
} }
/* Destroy keys and secrets */ /* Destroy keys and secrets */
......
...@@ -35,10 +35,10 @@ ...@@ -35,10 +35,10 @@
/** Return available crypto functions. For now we have /** Return available crypto functions. For now we have
* *
* - Hash: HMAC-SHA256(Mandatory) * - Hash: HMAC-SHA256(Mandatory)
* - CipherBlock: AES128(Mandatory) * - CipherBlock: AES128(Mandatory), AES256(optional)
* - Auth Tag: HMAC-SHA132 and HMAC-SHA180 (These are mandatory for SRTP and depends on the SRTP implementation thus we can just suppose they are both available) * - Auth Tag: HMAC-SHA132 and HMAC-SHA180 (These are mandatory for SRTP and depends on the SRTP implementation thus we can just suppose they are both available)
* - Key Agreement: DHM3k(Mandatory), DHM2k(optional and shall not be used except on low power devices) * - Key Agreement: ECDH25519(not mentionned in RFC), ECDH448(not mentionned in RFC), DHM3k(Mandatory), DHM2k(optional and shall not be used except on low power devices)
* - Sas: base32(Mandatory), b256(pgp words) * - Sas: base32(Mandatory), b256(pgp words, optional)
*/ */
uint8_t bzrtpUtils_getAvailableCryptoTypes(uint8_t algoType, uint8_t availableTypes[7]) { uint8_t bzrtpUtils_getAvailableCryptoTypes(uint8_t algoType, uint8_t availableTypes[7]) {
...@@ -46,28 +46,45 @@ uint8_t bzrtpUtils_getAvailableCryptoTypes(uint8_t algoType, uint8_t availableTy ...@@ -46,28 +46,45 @@ uint8_t bzrtpUtils_getAvailableCryptoTypes(uint8_t algoType, uint8_t availableTy
case ZRTP_HASH_TYPE: case ZRTP_HASH_TYPE:
availableTypes[0] = ZRTP_HASH_S256; availableTypes[0] = ZRTP_HASH_S256;
return 1; return 1;
break;
case ZRTP_CIPHERBLOCK_TYPE: case ZRTP_CIPHERBLOCK_TYPE:
availableTypes[0] = ZRTP_CIPHER_AES1; availableTypes[0] = ZRTP_CIPHER_AES1;
availableTypes[1] = ZRTP_CIPHER_AES3; availableTypes[1] = ZRTP_CIPHER_AES3;
return 2; return 2;
break;
case ZRTP_AUTHTAG_TYPE: case ZRTP_AUTHTAG_TYPE:
availableTypes[0] = ZRTP_AUTHTAG_HS32; availableTypes[0] = ZRTP_AUTHTAG_HS32;
availableTypes[1] = ZRTP_AUTHTAG_HS80; availableTypes[1] = ZRTP_AUTHTAG_HS80;
return 2; return 2;
break;
case ZRTP_KEYAGREEMENT_TYPE: case ZRTP_KEYAGREEMENT_TYPE:
availableTypes[0] = ZRTP_KEYAGREEMENT_DH3k; {
availableTypes[1] = ZRTP_KEYAGREEMENT_DH2k; /* get availables types from bctoolbox */
availableTypes[2] = ZRTP_KEYAGREEMENT_Mult; /* This one shall always be at the end of the list, it is just to inform the peer ZRTP endpoint that we support the Multichannel ZRTP */ uint32_t available_key_agreements = bctbx_key_agreement_algo_list();
return 3; uint8_t index=0;
break; if (available_key_agreements&BCTBX_ECDH_X25519) {
availableTypes[index] = ZRTP_KEYAGREEMENT_X255;
index++;
}
if (available_key_agreements&BCTBX_ECDH_X448) {
availableTypes[index] = ZRTP_KEYAGREEMENT_X448;
index++;
}
/* DH3k is mandatory*/
availableTypes[index] = ZRTP_KEYAGREEMENT_DH3k;
index++;
if (available_key_agreements|BCTBX_DHM_2048) {
availableTypes[index] = ZRTP_KEYAGREEMENT_DH2k;
index++;
}
availableTypes[index] = ZRTP_KEYAGREEMENT_Mult; /* This one shall always be at the end of the list, it is just to inform the peer ZRTP endpoint that we support the Multichannel ZRTP */
return index+1;
}
case ZRTP_SAS_TYPE: /* the SAS function is implemented in cryptoUtils.c and then is not directly linked to the polarSSL crypto wrapper */ case ZRTP_SAS_TYPE: /* the SAS function is implemented in cryptoUtils.c and then is not directly linked to the polarSSL crypto wrapper */
availableTypes[0] = ZRTP_SAS_B32; availableTypes[0] = ZRTP_SAS_B32;
availableTypes[1] = ZRTP_SAS_B256; availableTypes[1] = ZRTP_SAS_B256;
return 2; return 2;
break;
default: default:
return 0; return 0;
} }
...@@ -331,7 +348,7 @@ int bzrtp_cryptoAlgoAgreement(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t ...@@ -331,7 +348,7 @@ int bzrtp_cryptoAlgoAgreement(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t
/* if the first choices are the same for both, select it */ /* if the first choices are the same for both, select it */
if (selfCommonKeyAgreementType[0] == peerCommonKeyAgreementType[0]) { if (selfCommonKeyAgreementType[0] == peerCommonKeyAgreementType[0]) {
zrtpChannelContext->keyAgreementAlgo = selfCommonKeyAgreementType[0]; zrtpChannelContext->keyAgreementAlgo = selfCommonKeyAgreementType[0];
} else { /* select the fastest of the two algoritm. Order is "DH2k", "EC25", "DH3k", "EC38", "EC52" */ } else { /* select the fastest of the two algoritm. Order is "DH2k", "E255", "EC25", "E448", "DH3k", "EC38", "EC52" is defined by value order from bzrtp.h */
if (peerCommonKeyAgreementType[0]<selfCommonKeyAgreementType[0]) { /* mapping to uint8_t is defined to have them in the fast to slow order */ if (peerCommonKeyAgreementType[0]<selfCommonKeyAgreementType[0]) { /* mapping to uint8_t is defined to have them in the fast to slow order */
zrtpChannelContext->keyAgreementAlgo = peerCommonKeyAgreementType[0]; zrtpChannelContext->keyAgreementAlgo = peerCommonKeyAgreementType[0];
} else { } else {
...@@ -485,6 +502,12 @@ int bzrtp_updateCryptoFunctionPointers(bzrtpChannelContext_t *zrtpChannelContext ...@@ -485,6 +502,12 @@ int bzrtp_updateCryptoFunctionPointers(bzrtpChannelContext_t *zrtpChannelContext
case ZRTP_KEYAGREEMENT_DH3k : case ZRTP_KEYAGREEMENT_DH3k :
zrtpChannelContext->keyAgreementLength = 384; zrtpChannelContext->keyAgreementLength = 384;
break; break;
case ZRTP_KEYAGREEMENT_X255 :
zrtpChannelContext->keyAgreementLength = 32;
break;
case ZRTP_KEYAGREEMENT_X448 :
zrtpChannelContext->keyAgreementLength = 56;
break;
default: default:
return ZRTP_CRYPTOAGREEMENT_INVALIDCIPHER; return ZRTP_CRYPTOAGREEMENT_INVALIDCIPHER;
break; break;
...@@ -677,8 +700,12 @@ uint8_t bzrtp_cryptoAlgoTypeStringToInt(uint8_t algoType[4], uint8_t algoFamily) ...@@ -677,8 +700,12 @@ uint8_t bzrtp_cryptoAlgoTypeStringToInt(uint8_t algoType[4], uint8_t algoFamily)
return ZRTP_KEYAGREEMENT_DH3k; return ZRTP_KEYAGREEMENT_DH3k;
} else if (memcmp(algoType, "DH2k", 4) == 0) { } else if (memcmp(algoType, "DH2k", 4) == 0) {
return ZRTP_KEYAGREEMENT_DH2k; return ZRTP_KEYAGREEMENT_DH2k;
} else if (memcmp(algoType, "E255", 4) == 0) {
return ZRTP_KEYAGREEMENT_X255;
} else if (memcmp(algoType, "EC25", 4) == 0) { } else if (memcmp(algoType, "EC25", 4) == 0) {
return ZRTP_KEYAGREEMENT_EC25; return ZRTP_KEYAGREEMENT_EC25;
} else if (memcmp(algoType, "E448", 4) == 0) {
return ZRTP_KEYAGREEMENT_X448;
} else if (memcmp(algoType, "EC38", 4) == 0) { } else if (memcmp(algoType, "EC38", 4) == 0) {
return ZRTP_KEYAGREEMENT_EC38; return ZRTP_KEYAGREEMENT_EC38;
} else if (memcmp(algoType, "EC52", 4) == 0) { } else if (memcmp(algoType, "EC52", 4) == 0) {
...@@ -760,9 +787,15 @@ void bzrtp_cryptoAlgoTypeIntToString(uint8_t algoTypeInt, uint8_t algoTypeString ...@@ -760,9 +787,15 @@ void bzrtp_cryptoAlgoTypeIntToString(uint8_t algoTypeInt, uint8_t algoTypeString
case ZRTP_KEYAGREEMENT_DH2k: case ZRTP_KEYAGREEMENT_DH2k:
memcpy(algoTypeString, "DH2k", 4); memcpy(algoTypeString, "DH2k", 4);
break; break;
case ZRTP_KEYAGREEMENT_X255:
memcpy(algoTypeString, "E255", 4);
break;
case ZRTP_KEYAGREEMENT_EC25: case ZRTP_KEYAGREEMENT_EC25:
memcpy(algoTypeString, "EC25", 4); memcpy(algoTypeString, "EC25", 4);
break; break;
case ZRTP_KEYAGREEMENT_X448:
memcpy(algoTypeString, "E448", 4);
break;
case ZRTP_KEYAGREEMENT_DH3k: case ZRTP_KEYAGREEMENT_DH3k:
memcpy(algoTypeString, "DH3k", 4); memcpy(algoTypeString, "DH3k", 4);
break; break;
......
...@@ -356,6 +356,8 @@ int bzrtp_packetParser(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpC ...@@ -356,6 +356,8 @@ int bzrtp_packetParser(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpC
/* commit message length depends on the key agreement type choosen (and set in the zrtpContext->keyAgreementAlgo) */ /* commit message length depends on the key agreement type choosen (and set in the zrtpContext->keyAgreementAlgo) */
switch(messageData->keyAgreementAlgo) { switch(messageData->keyAgreementAlgo) {
case ZRTP_KEYAGREEMENT_DH2k : case ZRTP_KEYAGREEMENT_DH2k :
case ZRTP_KEYAGREEMENT_X255 :
case ZRTP_KEYAGREEMENT_X448 :
case ZRTP_KEYAGREEMENT_EC25 : case ZRTP_KEYAGREEMENT_EC25 :
case ZRTP_KEYAGREEMENT_DH3k : case ZRTP_KEYAGREEMENT_DH3k :
case ZRTP_KEYAGREEMENT_EC38 : case ZRTP_KEYAGREEMENT_EC38 :
...@@ -847,6 +849,8 @@ int bzrtp_packetBuild(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpCh ...@@ -847,6 +849,8 @@ int bzrtp_packetBuild(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpCh
switch(messageData->keyAgreementAlgo) { switch(messageData->keyAgreementAlgo) {
case ZRTP_KEYAGREEMENT_DH2k : case ZRTP_KEYAGREEMENT_DH2k :
case ZRTP_KEYAGREEMENT_EC25 : case ZRTP_KEYAGREEMENT_EC25 :
case ZRTP_KEYAGREEMENT_X255 :
case ZRTP_KEYAGREEMENT_X448 :
case ZRTP_KEYAGREEMENT_DH3k : case ZRTP_KEYAGREEMENT_DH3k :
case ZRTP_KEYAGREEMENT_EC38 : case ZRTP_KEYAGREEMENT_EC38 :
case ZRTP_KEYAGREEMENT_EC52 : case ZRTP_KEYAGREEMENT_EC52 :
...@@ -1262,11 +1266,59 @@ bzrtpPacket_t *bzrtp_createZrtpPacket(bzrtpContext_t *zrtpContext, bzrtpChannelC ...@@ -1262,11 +1266,59 @@ bzrtpPacket_t *bzrtp_createZrtpPacket(bzrtpContext_t *zrtpContext, bzrtpChannelC
switch (zrtpChannelContext->keyAgreementAlgo) { switch (zrtpChannelContext->keyAgreementAlgo) {
case ZRTP_KEYAGREEMENT_DH2k: case ZRTP_KEYAGREEMENT_DH2k:
bctbx_keyAgreementAlgo = BCTBX_DHM_2048;
break;
case ZRTP_KEYAGREEMENT_DH3k: case ZRTP_KEYAGREEMENT_DH3k:
bctbx_keyAgreementAlgo = BCTBX_DHM_3072; {
bctbx_DHMContext_t *DHMContext = NULL;
if (zrtpChannelContext->keyAgreementAlgo==ZRTP_KEYAGREEMENT_DH2k) {
bctbx_keyAgreementAlgo = BCTBX_DHM_2048;
} else {
bctbx_keyAgreementAlgo = BCTBX_DHM_3072;
}
/* create DHM context */
DHMContext = (void *)bctbx_CreateDHMContext(bctbx_keyAgreementAlgo, secretLength);
if (DHMContext == NULL) {
free(zrtpPacket);
free(zrtpDHPartMessage);
*exitCode = BZRTP_CREATE_ERROR_UNABLETOCREATECRYPTOCONTEXT;
return NULL;
}
/* create private key and compute the public value */
bctbx_DHMCreatePublic(DHMContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, zrtpContext->RNGContext);
zrtpDHPartMessage->pv = (uint8_t *)malloc((zrtpChannelContext->keyAgreementLength)*sizeof(uint8_t));
memcpy(zrtpDHPartMessage->pv, DHMContext->self, zrtpChannelContext->keyAgreementLength);
zrtpContext->keyAgreementContext = (void *)DHMContext; /* save DHM context in zrtp Context */
zrtpContext->keyAgreementAlgo = zrtpChannelContext->keyAgreementAlgo; /* store algo in global context to be able to destroy it correctly*/
}
break; break;
case ZRTP_KEYAGREEMENT_X255:
case ZRTP_KEYAGREEMENT_X448:
{
bctbx_ECDHContext_t *ECDHContext = NULL;
if (zrtpChannelContext->keyAgreementAlgo==ZRTP_KEYAGREEMENT_X255) {
bctbx_keyAgreementAlgo = BCTBX_ECDH_X25519;
} else {
bctbx_keyAgreementAlgo = BCTBX_ECDH_X448;
}
/* Create the ECDH context */
ECDHContext = (void *)bctbx_CreateECDHContext(bctbx_keyAgreementAlgo);
if (ECDHContext == NULL) {
free(zrtpPacket);
free(zrtpDHPartMessage);
*exitCode = BZRTP_CREATE_ERROR_UNABLETOCREATECRYPTOCONTEXT;
return NULL;
}
/* create private key and compute the public value */
bctbx_ECDHCreateKeyPair(ECDHContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, zrtpContext->RNGContext);
zrtpDHPartMessage->pv = (uint8_t *)malloc((zrtpChannelContext->keyAgreementLength)*sizeof(uint8_t));
memcpy(zrtpDHPartMessage->pv, ECDHContext->selfPublic, zrtpChannelContext->keyAgreementLength);
zrtpContext->keyAgreementContext = (void *)ECDHContext; /* save ECDH context in zrtp Context */
zrtpContext->keyAgreementAlgo = zrtpChannelContext->keyAgreementAlgo; /* store algo in global context to be able to destroy it correctly*/
}
break;
default: default:
free(zrtpPacket); free(zrtpPacket);
free(zrtpDHPartMessage); free(zrtpDHPartMessage);
...@@ -1274,20 +1326,7 @@ bzrtpPacket_t *bzrtp_createZrtpPacket(bzrtpContext_t *zrtpContext, bzrtpChannelC ...@@ -1274,20 +1326,7 @@ bzrtpPacket_t *bzrtp_createZrtpPacket(bzrtpContext_t *zrtpContext, bzrtpChannelC
return NULL; return NULL;
break; break;
} }
zrtpContext->DHMContext = bctbx_CreateDHMContext(bctbx_keyAgreementAlgo, secretLength); /* attach the message data to the packet */
if (zrtpContext->DHMContext == NULL) {
free(zrtpPacket);
free(zrtpDHPartMessage);
*exitCode = BZRTP_CREATE_ERROR_UNABLETOCREATECRYPTOCONTEXT;
return NULL;
}
/* now compute the public value */
bctbx_DHMCreatePublic(zrtpContext->DHMContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, zrtpContext->RNGContext);
zrtpDHPartMessage->pv = (uint8_t *)malloc((zrtpChannelContext->keyAgreementLength)*sizeof(uint8_t));
memcpy(zrtpDHPartMessage->pv, zrtpContext->DHMContext->self, zrtpChannelContext->keyAgreementLength);
/* attach the message data to the packet */
zrtpPacket->messageData = zrtpDHPartMessage; zrtpPacket->messageData = zrtpDHPartMessage;
} }
break; /* MSGTYPE_DHPART1 and MSGTYPE_DHPART2 */ break; /* MSGTYPE_DHPART1 and MSGTYPE_DHPART2 */
...@@ -1581,6 +1620,12 @@ uint16_t computeKeyAgreementPrivateValueLength(uint8_t keyAgreementAlgo) { ...@@ -1581,6 +1620,12 @@ uint16_t computeKeyAgreementPrivateValueLength(uint8_t keyAgreementAlgo) {
case ZRTP_KEYAGREEMENT_DH2k : case ZRTP_KEYAGREEMENT_DH2k :
pvLength = 256; pvLength = 256;
break; break;
case ZRTP_KEYAGREEMENT_X255 :
pvLength = 32;
break;
case ZRTP_KEYAGREEMENT_X448 :
pvLength = 56;
break;
case ZRTP_KEYAGREEMENT_EC25 : case ZRTP_KEYAGREEMENT_EC25 :
pvLength = 64; pvLength = 64;
break; break;
......
...@@ -569,9 +569,18 @@ int state_keyAgreement_sendingCommit(bzrtpEvent_t event) { ...@@ -569,9 +569,18 @@ int state_keyAgreement_sendingCommit(bzrtpEvent_t event) {
zrtpChannelContext->peerPackets[DHPART_MESSAGE_STORE_ID] = zrtpPacket; zrtpChannelContext->peerPackets[DHPART_MESSAGE_STORE_ID] = zrtpPacket;
/* Compute the shared DH secret */ /* Compute the shared DH secret */
zrtpContext->DHMContext->peer = (uint8_t *)malloc(zrtpChannelContext->keyAgreementLength*sizeof(uint8_t)); if (zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH2k || zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH3k) {
memcpy (zrtpContext->DHMContext->peer, dhPart1Message->pv, zrtpChannelContext->keyAgreementLength); bctbx_DHMContext_t *DHMContext = (bctbx_DHMContext_t *)(zrtpContext->keyAgreementContext);
bctbx_DHMComputeSecret(zrtpContext->DHMContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, (void *)zrtpContext->RNGContext); DHMContext->peer = (uint8_t *)malloc(zrtpChannelContext->keyAgreementLength*sizeof(uint8_t));
memcpy (DHMContext->peer, dhPart1Message->pv, zrtpChannelContext->keyAgreementLength);
bctbx_DHMComputeSecret(DHMContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, (void *)zrtpContext->RNGContext);
}
if (zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X255 || zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X448) {
bctbx_ECDHContext_t *ECDHContext = (bctbx_ECDHContext_t *)(zrtpContext->keyAgreementContext);
ECDHContext->peerPublic = (uint8_t *)malloc(zrtpChannelContext->keyAgreementLength*sizeof(uint8_t));
memcpy (ECDHContext->peerPublic, dhPart1Message->pv, zrtpChannelContext->keyAgreementLength);
bctbx_ECDHComputeSecret(ECDHContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, (void *)zrtpContext->RNGContext);
}
/* Derive the s0 key */ /* Derive the s0 key */
bzrtp_computeS0DHMMode(zrtpContext, zrtpChannelContext); bzrtp_computeS0DHMMode(zrtpContext, zrtpChannelContext);
...@@ -867,9 +876,18 @@ int state_keyAgreement_responderSendingDHPart1(bzrtpEvent_t event) { ...@@ -867,9 +876,18 @@ int state_keyAgreement_responderSendingDHPart1(bzrtpEvent_t event) {
zrtpChannelContext->peerPackets[DHPART_MESSAGE_STORE_ID] = zrtpPacket; zrtpChannelContext->peerPackets[DHPART_MESSAGE_STORE_ID] = zrtpPacket;
/* Compute the shared DH secret */ /* Compute the shared DH secret */
zrtpContext->DHMContext->peer = (uint8_t *)malloc(zrtpChannelContext->keyAgreementLength*sizeof(uint8_t)); if (zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH2k || zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH3k) {
memcpy (zrtpContext->DHMContext->peer, dhPart2Message->pv, zrtpChannelContext->keyAgreementLength); bctbx_DHMContext_t *DHMContext = (bctbx_DHMContext_t *)(zrtpContext->keyAgreementContext);
bctbx_DHMComputeSecret(zrtpContext->DHMContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, (void *)zrtpContext->RNGContext); DHMContext->peer = (uint8_t *)malloc(zrtpChannelContext->keyAgreementLength*sizeof(uint8_t));
memcpy (DHMContext->peer, dhPart2Message->pv, zrtpChannelContext->keyAgreementLength);
bctbx_DHMComputeSecret(DHMContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, (void *)zrtpContext->RNGContext);
}
if (zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X255 || zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X448) {
bctbx_ECDHContext_t *ECDHContext = (bctbx_ECDHContext_t *)(zrtpContext->keyAgreementContext);
ECDHContext->peerPublic = (uint8_t *)malloc(zrtpChannelContext->keyAgreementLength*sizeof(uint8_t));
memcpy (ECDHContext->peerPublic, dhPart2Message->pv, zrtpChannelContext->keyAgreementLength);
bctbx_ECDHComputeSecret(ECDHContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, (void *)zrtpContext->RNGContext);
}
/* Derive the s0 key */ /* Derive the s0 key */
bzrtp_computeS0DHMMode(zrtpContext, zrtpChannelContext); bzrtp_computeS0DHMMode(zrtpContext, zrtpChannelContext);
...@@ -1892,7 +1910,15 @@ int bzrtp_computeS0DHMMode(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *z ...@@ -1892,7 +1910,15 @@ int bzrtp_computeS0DHMMode(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *z
dataToHash[3] = 0x01; dataToHash[3] = 0x01;
hashDataIndex = 4; hashDataIndex = 4;
memcpy(dataToHash+hashDataIndex, zrtpContext->DHMContext->key, zrtpChannelContext->keyAgreementLength); if (zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH2k || zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH3k) {
bctbx_DHMContext_t *DHMContext = (bctbx_DHMContext_t *)zrtpContext->keyAgreementContext;
memcpy(dataToHash+hashDataIndex, DHMContext->key, zrtpChannelContext->keyAgreementLength);
}
if (zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X255 || zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X448) {
bctbx_ECDHContext_t *ECDHContext = (bctbx_ECDHContext_t *)zrtpContext->keyAgreementContext;
memcpy(dataToHash+hashDataIndex, ECDHContext->sharedSecret, zrtpChannelContext->keyAgreementLength);
}
hashDataIndex += zrtpChannelContext->keyAgreementLength; hashDataIndex += zrtpChannelContext->keyAgreementLength;
memcpy(dataToHash+hashDataIndex, "ZRTP-HMAC-KDF", 13); memcpy(dataToHash+hashDataIndex, "ZRTP-HMAC-KDF", 13);
hashDataIndex += 13; hashDataIndex += 13;
...@@ -1949,8 +1975,14 @@ int bzrtp_computeS0DHMMode(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *z ...@@ -1949,8 +1975,14 @@ int bzrtp_computeS0DHMMode(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *z
zrtpContext->ZRTPSess); zrtpContext->ZRTPSess);
/* clean the DHM context (secret and key shall be erased by this operation) */ /* clean the DHM context (secret and key shall be erased by this operation) */
bctbx_DestroyDHMContext(zrtpContext->DHMContext); if (zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH2k || zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH3k) {
zrtpContext->DHMContext = NULL; bctbx_DestroyDHMContext((bctbx_DHMContext_t *)(zrtpContext->keyAgreementContext));
}
if (zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X255 || zrtpContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X448) {
bctbx_DestroyECDHContext((bctbx_ECDHContext_t *)(zrtpContext->keyAgreementContext));
}
zrtpContext->keyAgreementContext = NULL;
zrtpContext->keyAgreementAlgo = ZRTP_UNSET_ALGO;
/* now derive the other keys */ /* now derive the other keys */
return bzrtp_deriveKeysFromS0(zrtpContext, zrtpChannelContext); return bzrtp_deriveKeysFromS0(zrtpContext, zrtpChannelContext);
......
...@@ -76,8 +76,23 @@ static uint8_t bobQueueIndex = 0; ...@@ -76,8 +76,23 @@ static uint8_t bobQueueIndex = 0;
#define ALICE_SSRC_BASE 0x12345000 #define ALICE_SSRC_BASE 0x12345000
#define BOB_SSRC_BASE 0x87654000 #define BOB_SSRC_BASE 0x87654000
static cryptoParams_t defaultCryptoAlgoSelection = {{ZRTP_CIPHER_AES1},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_DH3k},1,{ZRTP_SAS_B32},1,{ZRTP_AUTHTAG_HS32},1,0}; static cryptoParams_t withoutX255 = {{ZRTP_CIPHER_AES1},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_DH3k},1,{ZRTP_SAS_B32},1,{ZRTP_AUTHTAG_HS32},1,0};
static cryptoParams_t defaultCryptoAlgoSelectionNoSASValidation = {{ZRTP_CIPHER_AES1},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_DH3k},1,{ZRTP_SAS_B32},1,{ZRTP_AUTHTAG_HS32},1,1}; static cryptoParams_t withX255 = {{ZRTP_CIPHER_AES1},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X255},1,{ZRTP_SAS_B32},1,{ZRTP_AUTHTAG_HS32},1,0};
cryptoParams_t *defaultCryptoAlgoSelection(void) {
if (bctbx_key_agreement_algo_list()&BCTBX_ECDH_X25519) {
return &withX255;
}
return &withoutX255;
}
static cryptoParams_t withoutX255noSAS = {{ZRTP_CIPHER_AES1},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_DH3k},1,{ZRTP_SAS_B32},1,{ZRTP_AUTHTAG_HS32},1,1};
static cryptoParams_t withX255noSAS = {{ZRTP_CIPHER_AES1},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X255},1,{ZRTP_SAS_B32},1,{ZRTP_AUTHTAG_HS32},1,1};
cryptoParams_t *defaultCryptoAlgoSelectionNoSASValidation(void) {
if (bctbx_key_agreement_algo_list()&BCTBX_ECDH_X25519) {
return &withX255noSAS;
}
return &withoutX255noSAS;
}
/* static global settings and their reset function */ /* static global settings and their reset function */
static uint64_t msSTC = 0; /* Simulation Time Coordinated start at 0 and increment it at each sleep, is in milliseconds */ static uint64_t msSTC = 0; /* Simulation Time Coordinated start at 0 and increment it at each sleep, is in milliseconds */
...@@ -557,6 +572,31 @@ void test_cacheless_exchange(void) { ...@@ -557,6 +572,31 @@ void test_cacheless_exchange(void) {
{{0},0,{0},0,{0},0,{0},0,{0},0,0}, /* this pattern will end the run because cipher nb is 0 */ {{0},0,{0},0,{0},0,{0},0,{0},0,0}, /* this pattern will end the run because cipher nb is 0 */
}; };
/* serie tested only if ECDH is available */
cryptoParams_t ecdh_patterns[] = {
{{ZRTP_CIPHER_AES1},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X448},1,{ZRTP_SAS_B32},1,{ZRTP_AUTHTAG_HS32},1,0},
{{ZRTP_CIPHER_AES1},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X448},1,{ZRTP_SAS_B32},1,{ZRTP_AUTHTAG_HS80},1,0},
{{ZRTP_CIPHER_AES1},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X448},1,{ZRTP_SAS_B256},1,{ZRTP_AUTHTAG_HS32},1,0},
{{ZRTP_CIPHER_AES1},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X448},1,{ZRTP_SAS_B256},1,{ZRTP_AUTHTAG_HS80},1,0},
{{ZRTP_CIPHER_AES1},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X255},1,{ZRTP_SAS_B32},1,{ZRTP_AUTHTAG_HS32},1,0},
{{ZRTP_CIPHER_AES1},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X255},1,{ZRTP_SAS_B32},1,{ZRTP_AUTHTAG_HS80},1,0},
{{ZRTP_CIPHER_AES1},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X255},1,{ZRTP_SAS_B256},1,{ZRTP_AUTHTAG_HS32},1,0},
{{ZRTP_CIPHER_AES1},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X255},1,{ZRTP_SAS_B256},1,{ZRTP_AUTHTAG_HS80},1,0},
{{ZRTP_CIPHER_AES3},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X448},1,{ZRTP_SAS_B32},1,{ZRTP_AUTHTAG_HS32},1,0},
{{ZRTP_CIPHER_AES3},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X448},1,{ZRTP_SAS_B32},1,{ZRTP_AUTHTAG_HS80},1,0},
{{ZRTP_CIPHER_AES3},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X448},1,{ZRTP_SAS_B256},1,{ZRTP_AUTHTAG_HS32},1,0},
{{ZRTP_CIPHER_AES3},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X448},1,{ZRTP_SAS_B256},1,{ZRTP_AUTHTAG_HS80},1,0},
{{ZRTP_CIPHER_AES3},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X255},1,{ZRTP_SAS_B32},1,{ZRTP_AUTHTAG_HS32},1,0},
{{ZRTP_CIPHER_AES3},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X255},1,{ZRTP_SAS_B32},1,{ZRTP_AUTHTAG_HS80},1,0},
{{ZRTP_CIPHER_AES3},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X255},1,{ZRTP_SAS_B256},1,{ZRTP_AUTHTAG_HS32},1,0},
{{ZRTP_CIPHER_AES3},1,{ZRTP_HASH_S256},1,{ZRTP_KEYAGREEMENT_X255},1,{ZRTP_SAS_B256},1,{ZRTP_AUTHTAG_HS80},1,0},
{{0},0,{0},0,{0},0,{0},0,{0},0,0}, /* this pattern will end the run because cipher nb is 0 */
};
pattern = &patterns[0]; /* pattern is a pointer to current pattern */ pattern = &patterns[0]; /* pattern is a pointer to current pattern */
while (pattern->cipherNb!=0) { while (pattern->cipherNb!=0) {
...@@ -564,7 +604,14 @@ void test_cacheless_exchange(void) { ...@@ -564,7 +604,14 @@ void test_cacheless_exchange(void) {
pattern++; /* point to next row in the array of patterns */ pattern++; /* point to next row in the array of patterns */
} }
BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, &defaultCryptoAlgoSelection, NULL, NULL, NULL, NULL), 0, int, "%x"); /* with ECDH agreement types if available */
if (bctbx_key_agreement_algo_list()&BCTBX_ECDH_X25519) {
pattern = &ecdh_patterns[0]; /* pattern is a pointer to current pattern */
BC_ASSERT_EQUAL(multichannel_exchange(pattern, pattern, pattern, NULL, NULL, NULL, NULL), 0, int, "%x");
pattern++; /* point to next row in the array of patterns */
}
BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, defaultCryptoAlgoSelection(), NULL, NULL, NULL, NULL), 0, int, "%x");
} }
void test_loosy_network(void) { void test_loosy_network(void) {
...@@ -578,7 +625,7 @@ void test_loosy_network(void) { ...@@ -578,7 +625,7 @@ void test_loosy_network(void) {
resetGlobalParams(); resetGlobalParams();
timeOutLimit =100000; //outrageous time limit just to be sure to complete, not run in real time anyway timeOutLimit =100000; //outrageous time limit just to be sure to complete, not run in real time anyway
loosePacketPercentage=i; loosePacketPercentage=i;
BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, &defaultCryptoAlgoSelection, NULL, NULL, NULL, NULL), 0, int, "%x"); BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, defaultCryptoAlgoSelection(), NULL, NULL, NULL, NULL), 0, int, "%x");
} }
} }
} }
...@@ -604,7 +651,7 @@ void test_cache_enabled_exchange(void) { ...@@ -604,7 +651,7 @@ void test_cache_enabled_exchange(void) {
bzrtptester_sqlite3_open(bc_tester_file("tmpZIDBob_simpleCache.sqlite"), &bobDB); bzrtptester_sqlite3_open(bc_tester_file("tmpZIDBob_simpleCache.sqlite"), &bobDB);
/* make a first exchange */ /* make a first exchange */
BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, &defaultCryptoAlgoSelection, aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org"), 0, int, "%x"); BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, defaultCryptoAlgoSelection(), aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org"), 0, int, "%x");
/* after the first exchange we shall have both pvs values at 1 and both rs1 identical and rs2 null, retrieve them from cache and check it */ /* after the first exchange we shall have both pvs values at 1 and both rs1 identical and rs2 null, retrieve them from cache and check it */
/* first get each ZIDs, note give NULL as RNG context may lead to segfault in case of error(caches were not created correctly)*/ /* first get each ZIDs, note give NULL as RNG context may lead to segfault in case of error(caches were not created correctly)*/
...@@ -633,7 +680,7 @@ void test_cache_enabled_exchange(void) { ...@@ -633,7 +680,7 @@ void test_cache_enabled_exchange(void) {
BC_ASSERT_EQUAL(*colValuesBob[2], 1, int, "%d"); BC_ASSERT_EQUAL(*colValuesBob[2], 1, int, "%d");
/* make a second exchange */ /* make a second exchange */
BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, &defaultCryptoAlgoSelection, aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org"), 0, int, "%x"); BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, defaultCryptoAlgoSelection(), aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org"), 0, int, "%x");
/* read new values in cache, ZIDs and zuids must be identical, read alice first to be able to check rs2 with old rs1 */ /* read new values in cache, ZIDs and zuids must be identical, read alice first to be able to check rs2 with old rs1 */
BC_ASSERT_EQUAL(bzrtp_cache_read((void *)aliceDB, zuidAlice, "zrtp", colNames, colValuesAlice, colLengthAlice, 3), 0, int, "%x"); BC_ASSERT_EQUAL(bzrtp_cache_read((void *)aliceDB, zuidAlice, "zrtp", colNames, colValuesAlice, colLengthAlice, 3), 0, int, "%x");
/* check what is now rs2 is the old rs1 */ /* check what is now rs2 is the old rs1 */
...@@ -688,7 +735,7 @@ void test_cache_mismatch_exchange(void) { ...@@ -688,7 +735,7 @@ void test_cache_mismatch_exchange(void) {
bzrtptester_sqlite3_open(bc_tester_file("tmpZIDBob_cacheMismatch.sqlite"), &bobDB); bzrtptester_sqlite3_open(bc_tester_file("tmpZIDBob_cacheMismatch.sqlite"), &bobDB);
/* make a first exchange */ /* make a first exchange */
BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, &defaultCryptoAlgoSelection, aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org"), 0, int, "%x"); BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, defaultCryptoAlgoSelection(), aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org"), 0, int, "%x");
/* after the first exchange we shall have both pvs values at 1 and both rs1 identical and rs2 null, retrieve them from cache and check it */ /* after the first exchange we shall have both pvs values at 1 and both rs1 identical and rs2 null, retrieve them from cache and check it */
/* first get each ZIDs, note give NULL as RNG context may lead to segfault in case of error(caches were not created correctly)*/ /* first get each ZIDs, note give NULL as RNG context may lead to segfault in case of error(caches were not created correctly)*/
...@@ -722,7 +769,7 @@ void test_cache_mismatch_exchange(void) { ...@@ -722,7 +769,7 @@ void test_cache_mismatch_exchange(void) {
/* make a second exchange : we have a cache mismatch(both on Bob and Alice side), wich means rs1 will not be backed up in rs2 which shall be NULL again */ /* make a second exchange : we have a cache mismatch(both on Bob and Alice side), wich means rs1 will not be backed up in rs2 which shall be NULL again */
/* rs1 will be in sync has the SAS comparison will succeed and pvs will be set to 1*/ /* rs1 will be in sync has the SAS comparison will succeed and pvs will be set to 1*/
BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, &defaultCryptoAlgoSelection, aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org"), RET_CACHE_MISMATCH<<16|RET_CACHE_MISMATCH, int, "%x"); BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, defaultCryptoAlgoSelection(), aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org"), RET_CACHE_MISMATCH<<16|RET_CACHE_MISMATCH, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_read((void *)bobDB, zuidBob, "zrtp", colNames, colValuesBob, colLengthBob, 3), 0, int, "%x"); BC_ASSERT_EQUAL(bzrtp_cache_read((void *)bobDB, zuidBob, "zrtp", colNames, colValuesBob, colLengthBob, 3), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_read((void *)aliceDB, zuidAlice, "zrtp", colNames, colValuesAlice, colLengthAlice, 3), 0, int, "%x"); BC_ASSERT_EQUAL(bzrtp_cache_read((void *)aliceDB, zuidAlice, "zrtp", colNames, colValuesAlice, colLengthAlice, 3), 0, int, "%x");
...@@ -748,7 +795,7 @@ void test_cache_mismatch_exchange(void) { ...@@ -748,7 +795,7 @@ void test_cache_mismatch_exchange(void) {
/* make a third exchange : we have a cache mismatch(on Bob side only), wich means rs1 will not be backed up in rs2 which shall be NULL again */ /* make a third exchange : we have a cache mismatch(on Bob side only), wich means rs1 will not be backed up in rs2 which shall be NULL again */
/* rs1 will be in sync has the SAS comparison will succeed and pvs will be set to 1*/ /* rs1 will be in sync has the SAS comparison will succeed and pvs will be set to 1*/
BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, &defaultCryptoAlgoSelection, aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org"), RET_CACHE_MISMATCH<<16, int, "%x"); BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, defaultCryptoAlgoSelection(), aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org"), RET_CACHE_MISMATCH<<16, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_read((void *)bobDB, zuidBob, "zrtp", colNames, colValuesBob, colLengthBob, 3), 0, int, "%x"); BC_ASSERT_EQUAL(bzrtp_cache_read((void *)bobDB, zuidBob, "zrtp", colNames, colValuesBob, colLengthBob, 3), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_read((void *)aliceDB, zuidAlice, "zrtp", colNames, colValuesAlice, colLengthAlice, 3), 0, int, "%x"); BC_ASSERT_EQUAL(bzrtp_cache_read((void *)aliceDB, zuidAlice, "zrtp", colNames, colValuesAlice, colLengthAlice, 3), 0, int, "%x");
...@@ -800,7 +847,7 @@ void test_cache_sas_not_confirmed(void) { ...@@ -800,7 +847,7 @@ void test_cache_sas_not_confirmed(void) {
bzrtptester_sqlite3_open(bc_tester_file("tmpZIDBob_simpleCache.sqlite"), &bobDB); bzrtptester_sqlite3_open(bc_tester_file("tmpZIDBob_simpleCache.sqlite"), &bobDB);
/* make a first exchange, Alice is instructed to not validate the SAS */ /* make a first exchange, Alice is instructed to not validate the SAS */
BC_ASSERT_EQUAL(multichannel_exchange_pvs_params(&defaultCryptoAlgoSelectionNoSASValidation, &defaultCryptoAlgoSelection, &defaultCryptoAlgoSelection, aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org", TRUE, 0, 0), 0, int, "%x"); BC_ASSERT_EQUAL(multichannel_exchange_pvs_params(defaultCryptoAlgoSelectionNoSASValidation(), defaultCryptoAlgoSelection(), defaultCryptoAlgoSelection(), aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org", TRUE, 0, 0), 0, int, "%x");
/* after the first exchange we shall have alice pvs at 0 and bob at 1 and both rs1 identical and rs2 null, retrieve them from cache and check it */ /* after the first exchange we shall have alice pvs at 0 and bob at 1 and both rs1 identical and rs2 null, retrieve them from cache and check it */
/* first get each ZIDs, note give NULL as RNG context may lead to segfault in case of error(caches were not created correctly)*/ /* first get each ZIDs, note give NULL as RNG context may lead to segfault in case of error(caches were not created correctly)*/
...@@ -829,7 +876,7 @@ void test_cache_sas_not_confirmed(void) { ...@@ -829,7 +876,7 @@ void test_cache_sas_not_confirmed(void) {
/* make a second exchange, the PVS flag returned by both side shall be 0 as Alice did not validate hers on previous exchange */ /* make a second exchange, the PVS flag returned by both side shall be 0 as Alice did not validate hers on previous exchange */
/* but let them both validate this one */ /* but let them both validate this one */
BC_ASSERT_EQUAL(multichannel_exchange_pvs_params(NULL, NULL, &defaultCryptoAlgoSelection, aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org", TRUE, 0, 0), 0, int, "%x"); BC_ASSERT_EQUAL(multichannel_exchange_pvs_params(NULL, NULL, defaultCryptoAlgoSelection(), aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org", TRUE, 0, 0), 0, int, "%x");