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,31 +1266,66 @@ bzrtpPacket_t *bzrtp_createZrtpPacket(bzrtpContext_t *zrtpContext, bzrtpChannelC ...@@ -1262,31 +1266,66 @@ 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_DHMContext_t *DHMContext = NULL;
if (zrtpChannelContext->keyAgreementAlgo==ZRTP_KEYAGREEMENT_DH2k) {
bctbx_keyAgreementAlgo = BCTBX_DHM_2048;
} else {
bctbx_keyAgreementAlgo = BCTBX_DHM_3072; bctbx_keyAgreementAlgo = BCTBX_DHM_3072;
break; }
default: /* create DHM context */
DHMContext = (void *)bctbx_CreateDHMContext(bctbx_keyAgreementAlgo, secretLength);
if (DHMContext == NULL) {
free(zrtpPacket); free(zrtpPacket);
free(zrtpDHPartMessage); free(zrtpDHPartMessage);
*exitCode = BZRTP_CREATE_ERROR_UNABLETOCREATECRYPTOCONTEXT; *exitCode = BZRTP_CREATE_ERROR_UNABLETOCREATECRYPTOCONTEXT;
return NULL; 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;
} }
zrtpContext->DHMContext = bctbx_CreateDHMContext(bctbx_keyAgreementAlgo, secretLength);
if (zrtpContext->DHMContext == NULL) { /* Create the ECDH context */
ECDHContext = (void *)bctbx_CreateECDHContext(bctbx_keyAgreementAlgo);
if (ECDHContext == NULL) {
free(zrtpPacket); free(zrtpPacket);
free(zrtpDHPartMessage); free(zrtpDHPartMessage);
*exitCode = BZRTP_CREATE_ERROR_UNABLETOCREATECRYPTOCONTEXT; *exitCode = BZRTP_CREATE_ERROR_UNABLETOCREATECRYPTOCONTEXT;
return NULL; return NULL;
} }
/* create private key and compute the public value */
/* now compute the public value */ bctbx_ECDHCreateKeyPair(ECDHContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, zrtpContext->RNGContext);
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)); zrtpDHPartMessage->pv = (uint8_t *)malloc((zrtpChannelContext->keyAgreementLength)*sizeof(uint8_t));
memcpy(zrtpDHPartMessage->pv, zrtpContext->DHMContext->self, zrtpChannelContext->keyAgreementLength); 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:
free(zrtpPacket);
free(zrtpDHPartMessage);
*exitCode = BZRTP_CREATE_ERROR_UNABLETOCREATECRYPTOCONTEXT;
return NULL;
break;
}
/* attach the message data to the packet */ /* attach the message data to the packet */
zrtpPacket->messageData = zrtpDHPartMessage; zrtpPacket->messageData = zrtpDHPartMessage;
} }
...@@ -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);
......
This diff is collapsed.
...@@ -115,7 +115,14 @@ void test_CRC32(void) { ...@@ -115,7 +115,14 @@ void test_CRC32(void) {
BC_ASSERT_TRUE(bzrtp_CRC32(patterCRCinput[i], patternCRCLength[i]) == patternCRCoutput[i]); BC_ASSERT_TRUE(bzrtp_CRC32(patterCRCinput[i], patternCRCLength[i]) == patternCRCoutput[i]);
} }
} }
/* expected result of tests vary according to default key agreement algorithm */
/* if EC25519 is available, this is the default, DH3k otherwise */
static uint8_t getDefaultKeyAgreementAlgo() {
if (bctbx_key_agreement_algo_list()&BCTBX_ECDH_X25519) {
return ZRTP_KEYAGREEMENT_X255;
}
return ZRTP_KEYAGREEMENT_DH3k;
}
static void setHelloMessageAlgo(bzrtpHelloMessage_t *helloMessage, uint8_t algoType, uint8_t types[7], const uint8_t typesCount) { static void setHelloMessageAlgo(bzrtpHelloMessage_t *helloMessage, uint8_t algoType, uint8_t types[7], const uint8_t typesCount) {
switch(algoType) { switch(algoType) {
case ZRTP_HASH_TYPE: case ZRTP_HASH_TYPE:
...@@ -153,17 +160,17 @@ static int compareAllAlgoTypes(bzrtpChannelContext_t *zrtpChannelContext, uint8_ ...@@ -153,17 +160,17 @@ static int compareAllAlgoTypes(bzrtpChannelContext_t *zrtpChannelContext, uint8_
static int compareAllAlgoTypesWithExpectedChangedOnly(bzrtpChannelContext_t *zrtpChannelContext, uint8_t expectedAlgoType, uint8_t expectedType) { static int compareAllAlgoTypesWithExpectedChangedOnly(bzrtpChannelContext_t *zrtpChannelContext, uint8_t expectedAlgoType, uint8_t expectedType) {
switch(expectedAlgoType) { switch(expectedAlgoType) {
case ZRTP_HASH_TYPE: case ZRTP_HASH_TYPE:
return compareAllAlgoTypes(zrtpChannelContext, expectedType, ZRTP_CIPHER_AES1, ZRTP_AUTHTAG_HS32, ZRTP_KEYAGREEMENT_DH3k, ZRTP_SAS_B32); return compareAllAlgoTypes(zrtpChannelContext, expectedType, ZRTP_CIPHER_AES1, ZRTP_AUTHTAG_HS32, getDefaultKeyAgreementAlgo(), ZRTP_SAS_B32);
case ZRTP_CIPHERBLOCK_TYPE: case ZRTP_CIPHERBLOCK_TYPE:
return compareAllAlgoTypes(zrtpChannelContext, ZRTP_HASH_S256, expectedType, ZRTP_AUTHTAG_HS32, ZRTP_KEYAGREEMENT_DH3k, ZRTP_SAS_B32); return compareAllAlgoTypes(zrtpChannelContext, ZRTP_HASH_S256, expectedType, ZRTP_AUTHTAG_HS32, getDefaultKeyAgreementAlgo(), ZRTP_SAS_B32);
case ZRTP_AUTHTAG_TYPE: case ZRTP_AUTHTAG_TYPE:
return compareAllAlgoTypes(zrtpChannelContext, ZRTP_HASH_S256, ZRTP_CIPHER_AES1, expectedType, ZRTP_KEYAGREEMENT_DH3k, ZRTP_SAS_B32); return compareAllAlgoTypes(zrtpChannelContext, ZRTP_HASH_S256, ZRTP_CIPHER_AES1, expectedType, getDefaultKeyAgreementAlgo(), ZRTP_SAS_B32);
case ZRTP_KEYAGREEMENT_TYPE: case ZRTP_KEYAGREEMENT_TYPE:
return compareAllAlgoTypes(zrtpChannelContext, ZRTP_HASH_S256, ZRTP_CIPHER_AES1, ZRTP_AUTHTAG_HS32, expectedType, ZRTP_SAS_B32); return compareAllAlgoTypes(zrtpChannelContext, ZRTP_HASH_S256, ZRTP_CIPHER_AES1, ZRTP_AUTHTAG_HS32, expectedType, ZRTP_SAS_B32);
case ZRTP_SAS_TYPE: case ZRTP_SAS_TYPE:
return compareAllAlgoTypes(zrtpChannelContext, ZRTP_HASH_S256, ZRTP_CIPHER_AES1, ZRTP_AUTHTAG_HS32, ZRTP_KEYAGREEMENT_DH3k, expectedType); return compareAllAlgoTypes(zrtpChannelContext, ZRTP_HASH_S256, ZRTP_CIPHER_AES1, ZRTP_AUTHTAG_HS32, getDefaultKeyAgreementAlgo(), expectedType);
default: default:
return compareAllAlgoTypes(zrtpChannelContext, ZRTP_HASH_S256, ZRTP_CIPHER_AES1, ZRTP_AUTHTAG_HS32, ZRTP_KEYAGREEMENT_DH3k, ZRTP_SAS_B32); return compareAllAlgoTypes(zrtpChannelContext, ZRTP_HASH_S256, ZRTP_CIPHER_AES1, ZRTP_AUTHTAG_HS32, getDefaultKeyAgreementAlgo(), ZRTP_SAS_B32);
} }
} }
...@@ -296,7 +303,7 @@ void test_algoAgreement(void) { ...@@ -296,7 +303,7 @@ void test_algoAgreement(void) {
struct st_algo_type *cipher_type; struct st_algo_type *cipher_type;
/* check defaults */ /* check defaults */
BC_ASSERT_TRUE(testAlgoTypeWithPacket(ZRTP_UNSET_ALGO, NULL, 0, ZRTP_KEYAGREEMENT_DH3k)); BC_ASSERT_TRUE(testAlgoTypeWithPacket(ZRTP_UNSET_ALGO, NULL, 0, getDefaultKeyAgreementAlgo()));
/* key agreement type */ /* key agreement type */
agreement_type_with_packet = &agreement_types_with_packet[0]; agreement_type_with_packet = &agreement_types_with_packet[0];
...@@ -391,6 +398,15 @@ void test_algoSetterGetter(void) { ...@@ -391,6 +398,15 @@ void test_algoSetterGetter(void) {
{ {ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_DH3k}, 8, {ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_Mult}, 2 }, { {ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_DH3k}, 8, {ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_Mult}, 2 },
{ {ZRTP_UNSET_ALGO}, 0, {ZRTP_UNSET_ALGO}, 0, } { {ZRTP_UNSET_ALGO}, 0, {ZRTP_UNSET_ALGO}, 0, }
}; };
/* Define another set used only if ECDH agreements are availables */
struct st_algo_setter_getter ecdh_agreement_types[] = {
{ {ZRTP_KEYAGREEMENT_X255}, 1, {ZRTP_KEYAGREEMENT_X255, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_Mult}, 3 },
{ {ZRTP_KEYAGREEMENT_X448}, 1, {ZRTP_KEYAGREEMENT_X448, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_Mult}, 3 },
{ {ZRTP_KEYAGREEMENT_X255, ZRTP_KEYAGREEMENT_X448}, 2, {ZRTP_KEYAGREEMENT_X255, ZRTP_KEYAGREEMENT_X448, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_Mult}, 4 },
{ {ZRTP_KEYAGREEMENT_X448, ZRTP_KEYAGREEMENT_X255}, 2, {ZRTP_KEYAGREEMENT_X448, ZRTP_KEYAGREEMENT_X255, ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_Mult}, 4 },
{ {ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_X448, ZRTP_KEYAGREEMENT_X255}, 3, {ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_X448, ZRTP_KEYAGREEMENT_X255, ZRTP_KEYAGREEMENT_Mult}, 4 },
{ {ZRTP_UNSET_ALGO}, 0, {ZRTP_UNSET_ALGO}, 0, }
};
struct st_algo_setter_getter *agreement_type; struct st_algo_setter_getter *agreement_type;
struct st_algo_setter_getter cipher_types[] = { struct st_algo_setter_getter cipher_types[] = {
{ {ZRTP_CIPHER_AES1}, 1, {ZRTP_CIPHER_AES1}, 1 }, { {ZRTP_CIPHER_AES1}, 1, {ZRTP_CIPHER_AES1}, 1 },
...@@ -417,6 +433,15 @@ void test_algoSetterGetter(void) { ...@@ -417,6 +433,15 @@ void test_algoSetterGetter(void) {
agreement_type++; agreement_type++;
} }
/* ECDH agreement type */
if (bctbx_key_agreement_algo_list()&BCTBX_ECDH_X25519) {
agreement_type = &ecdh_agreement_types[0];
while (agreement_type->contextTypesCount > 0) {
BC_ASSERT_TRUE(testAlgoSetterGetter(ZRTP_KEYAGREEMENT_TYPE, agreement_type->contextTypes, agreement_type->contextTypesCount, agreement_type->expectedTypes, agreement_type->expectedTypesCount));
agreement_type++;
}
}
/* cipher type */ /* cipher type */
cipher_type = &cipher_types[0]; cipher_type = &cipher_types[0];
while (cipher_type->contextTypesCount > 0) { while (cipher_type->contextTypesCount > 0) {
...@@ -451,6 +476,7 @@ void test_addMandatoryCryptoTypesIfNeeded(void) { ...@@ -451,6 +476,7 @@ void test_addMandatoryCryptoTypesIfNeeded(void) {
{ ZRTP_CIPHERBLOCK_TYPE, {ZRTP_UNSET_ALGO}, 0, {ZRTP_CIPHER_AES1}, 1 }, { ZRTP_CIPHERBLOCK_TYPE, {ZRTP_UNSET_ALGO}, 0, {ZRTP_CIPHER_AES1}, 1 },
{ ZRTP_AUTHTAG_TYPE, {ZRTP_UNSET_ALGO}, 0, {ZRTP_AUTHTAG_HS32, ZRTP_AUTHTAG_HS80}, 2 }, { ZRTP_AUTHTAG_TYPE, {ZRTP_UNSET_ALGO}, 0, {ZRTP_AUTHTAG_HS32, ZRTP_AUTHTAG_HS80}, 2 },
{ ZRTP_KEYAGREEMENT_TYPE, {ZRTP_UNSET_ALGO}, 0, {ZRTP_KEYAGREEMENT_DH3k}, 1 }, { ZRTP_KEYAGREEMENT_TYPE, {ZRTP_UNSET_ALGO}, 0, {ZRTP_KEYAGREEMENT_DH3k}, 1 },
{ ZRTP_KEYAGREEMENT_TYPE, {ZRTP_KEYAGREEMENT_X255}, 1, {ZRTP_KEYAGREEMENT_DH3k, ZRTP_KEYAGREEMENT_X255}, 2 },
{ ZRTP_SAS_TYPE, {ZRTP_UNSET_ALGO}, 0, {ZRTP_SAS_B32}, 1 }, { ZRTP_SAS_TYPE, {ZRTP_UNSET_ALGO}, 0, {ZRTP_SAS_B32}, 1 },
{ ZRTP_AUTHTAG_TYPE, {ZRTP_AUTHTAG_HS32, ZRTP_AUTHTAG_HS80}, 2, {ZRTP_AUTHTAG_HS32, ZRTP_AUTHTAG_HS80}, 2 }, { ZRTP_AUTHTAG_TYPE, {ZRTP_AUTHTAG_HS32, ZRTP_AUTHTAG_HS80}, 2, {ZRTP_AUTHTAG_HS32, ZRTP_AUTHTAG_HS80}, 2 },
{ ZRTP_AUTHTAG_TYPE, {ZRTP_AUTHTAG_HS80, ZRTP_AUTHTAG_HS32}, 2, {ZRTP_AUTHTAG_HS80, ZRTP_AUTHTAG_HS32}, 2 }, { ZRTP_AUTHTAG_TYPE, {ZRTP_AUTHTAG_HS80, ZRTP_AUTHTAG_HS32}, 2, {ZRTP_AUTHTAG_HS80, ZRTP_AUTHTAG_HS32}, 2 },
......
...@@ -706,9 +706,19 @@ void test_parserComplete() { ...@@ -706,9 +706,19 @@ void test_parserComplete() {
/* Now Alice shall check that the PV from bob is not 1 or Prime-1 TODO*/ /* Now Alice shall check that the PV from bob is not 1 or Prime-1 TODO*/
/* Compute the shared DH secret */ /* Compute the shared DH secret */
contextAlice->DHMContext->peer = (uint8_t *)malloc(contextAlice->channelContext[0]->keyAgreementLength*sizeof(uint8_t)); if (contextAlice->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH2k || contextAlice->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH3k) {
memcpy (contextAlice->DHMContext->peer, alice_DHPart1FromBob_message->pv, contextAlice->channelContext[0]->keyAgreementLength); bctbx_DHMContext_t *DHMContext = (bctbx_DHMContext_t *)(contextAlice->keyAgreementContext);
bctbx_DHMComputeSecret(contextAlice->DHMContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, (void *)contextAlice->RNGContext); DHMContext->peer = (uint8_t *)malloc(contextAlice->channelContext[0]->keyAgreementLength*sizeof(uint8_t));
memcpy (DHMContext->peer, alice_DHPart1FromBob_message->pv, contextAlice->channelContext[0]->keyAgreementLength);
bctbx_DHMComputeSecret(DHMContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, (void *)contextAlice->RNGContext);
}
if (contextAlice->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X255 || contextAlice->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X448) {
bctbx_ECDHContext_t *ECDHContext = (bctbx_ECDHContext_t *)(contextAlice->keyAgreementContext);
ECDHContext->peerPublic = (uint8_t *)malloc(contextAlice->channelContext[0]->keyAgreementLength*sizeof(uint8_t));
memcpy (ECDHContext->peerPublic, alice_DHPart1FromBob_message->pv, contextAlice->channelContext[0]->keyAgreementLength);
bctbx_ECDHComputeSecret(ECDHContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, (void *)contextAlice->RNGContext);
}
/* So Alice send bob her DHPart2 message which is already prepared and stored (we just need to update the sequence number) */ /* So Alice send bob her DHPart2 message which is already prepared and stored (we just need to update the sequence number) */
bzrtp_packetUpdateSequenceNumber(contextAlice->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID], contextAlice->channelContext[0]->selfSequenceNumber); bzrtp_packetUpdateSequenceNumber(contextAlice->channelContext[0]->selfPackets[DHPART_MESSAGE_STORE_ID], contextAlice->channelContext[0]->selfSequenceNumber);
...@@ -760,20 +770,45 @@ void test_parserComplete() { ...@@ -760,20 +770,45 @@ void test_parserComplete() {
/* Now Bob shall check that the PV from Alice is not 1 or Prime-1 TODO*/ /* Now Bob shall check that the PV from Alice is not 1 or Prime-1 TODO*/
/* Compute the shared DH secret */ /* Compute the shared DH secret */
contextBob->DHMContext->peer = (uint8_t *)malloc(contextBob->channelContext[0]->keyAgreementLength*sizeof(uint8_t)); if (contextBob->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH2k || contextBob->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH3k) {
memcpy (contextBob->DHMContext->peer, bob_DHPart2FromAlice_message->pv, contextBob->channelContext[0]->keyAgreementLength); bctbx_DHMContext_t *DHMContext = (bctbx_DHMContext_t *)(contextBob->keyAgreementContext);
bctbx_DHMComputeSecret(contextBob->DHMContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, (void *)contextAlice->RNGContext); DHMContext->peer = (uint8_t *)malloc(contextBob->channelContext[0]->keyAgreementLength*sizeof(uint8_t));
memcpy (DHMContext->peer, bob_DHPart2FromAlice_message->pv, contextBob->channelContext[0]->keyAgreementLength);
bctbx_DHMComputeSecret(DHMContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, (void *)contextAlice->RNGContext);
}
if (contextBob->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X255 || contextBob->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X448) {
bctbx_ECDHContext_t *ECDHContext = (bctbx_ECDHContext_t *)(contextBob->keyAgreementContext);
ECDHContext->peerPublic = (uint8_t *)malloc(contextBob->channelContext[0]->keyAgreementLength*sizeof(uint8_t));
memcpy (ECDHContext->peerPublic, bob_DHPart2FromAlice_message->pv, contextBob->channelContext[0]->keyAgreementLength);
bctbx_ECDHComputeSecret(ECDHContext, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, (void *)contextAlice->RNGContext);
}
/* JUST FOR TEST: check that the generated secrets are the same */ /* JUST FOR TEST: check that the generated secrets are the same */
secretLength = bob_DHPart2FromAlice->messageLength-84; /* length of generated secret is the same than public value */ secretLength = bob_DHPart2FromAlice->messageLength-84; /* length of generated secret is the same than public value */
if (memcmp(contextBob->DHMContext->key, contextAlice->DHMContext->key, secretLength)==0) { if (contextBob->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH2k || contextBob->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH3k) {
bctbx_DHMContext_t *DHMContextAlice = (bctbx_DHMContext_t *)(contextAlice->keyAgreementContext);
bctbx_DHMContext_t *DHMContextBob = (bctbx_DHMContext_t *)(contextBob->keyAgreementContext);
if (memcmp(DHMContextBob->key, DHMContextAlice->key, secretLength)==0) {
bzrtp_message("Secret Key correctly exchanged \n"); bzrtp_message("Secret Key correctly exchanged \n");
BC_PASS("Secret Key exchange OK"); BC_PASS("Secret Key exchange OK");
} else { } else {
BC_FAIL("Secret Key exchange failed"); BC_FAIL("Secret Key exchange failed");
bzrtp_message("ERROR : secretKey exchange failed!!\n"); bzrtp_message("ERROR : secretKey exchange failed!!\n");