Commit cb7e6ab5 authored by Ben Sartor's avatar Ben Sartor Committed by johan

make sure mandatory algorithm types are always supported

Signed-off-by: johan's avatarJohan Pascal <johan.pascal@belledonne-communications.com>
parent 3c9cd072
......@@ -137,6 +137,20 @@ int updateCryptoFunctionPointers(bzrtpChannelContext_t *zrtpChannelContext);
*/
uint8_t selectCommonAlgo(uint8_t masterArray[7], uint8_t masterArrayLength, uint8_t slaveArray[7], uint8_t slaveArrayLength, uint8_t commonArray[7]);
/**
* @brief add mandatory crypto functions if they are not already included
* - Hash function
* - Cipher Block
* - Auth Tag
* - Key agreement
* - SAS
*
* @param[in] algoType mapped to defines, must be in [ZRTP_HASH_TYPE, ZRTP_CIPHERBLOCK_TYPE, ZRTP_AUTHTAG_TYPE, ZRTP_KEYAGREEMENT_TYPE or ZRTP_SAS_TYPE]
* @param[in/out] algoTypes mapped to uint8_t value of the 4 char strings giving the algo types as string according to rfc section 5.1.2 to 5.1.6
* @param[in/out] algoTypesCount number of algo types
*/
void addMandatoryCryptoTypesIfNeeded(uint8_t algoType, uint8_t algoTypes[7], uint8_t *algoTypesCount);
/**
* @brief Map the string description of algo type to an int defined in cryptoWrapper.h
*
......
......@@ -50,6 +50,21 @@
*/
uint8_t bzrtpCrypto_getAvailableCryptoTypes(uint8_t algoType, uint8_t availableTypes[7]);
/**
* @brief Get the mandatory crypto functions
* - Hash function
* - Cipher Block
* - Auth Tag
* - Key agreement
* - SAS
*
* @param[in] algoType mapped to defines, must be in [ZRTP_HASH_TYPE, ZRTP_CIPHERBLOCK_TYPE, ZRTP_AUTHTAG_TYPE, ZRTP_KEYAGREEMENT_TYPE or ZRTP_SAS_TYPE]
* @param[out] mandatoryTypes mapped to uint8_t value of the 4 char strings giving the available types as string according to rfc section 5.1.2 to 5.1.6
*
* @return number of mandatory types, 0 on error
*/
uint8_t bzrtpCrypto_getMandatoryCryptoTypes(uint8_t algoType, uint8_t mandatoryTypes[7]);
/**
*
* @brief The context structure to the Random Number Generator
......
......@@ -824,18 +824,23 @@ void bzrtp_setSupportedCryptoTypes(bzrtpContext_t *zrtpContext, uint8_t algoType
switch(algoType) {
case ZRTP_HASH_TYPE:
zrtpContext->hc = selectCommonAlgo(supportedTypes, supportedTypesCount, implementedTypes, implementedTypesCount, zrtpContext->supportedHash);
addMandatoryCryptoTypesIfNeeded(algoType, zrtpContext->supportedHash, &zrtpContext->hc);
break;
case ZRTP_CIPHERBLOCK_TYPE:
zrtpContext->cc = selectCommonAlgo(supportedTypes, supportedTypesCount, implementedTypes, implementedTypesCount, zrtpContext->supportedCipher);
addMandatoryCryptoTypesIfNeeded(algoType, zrtpContext->supportedCipher, &zrtpContext->cc);
break;
case ZRTP_AUTHTAG_TYPE:
zrtpContext->ac = selectCommonAlgo(supportedTypes, supportedTypesCount, implementedTypes, implementedTypesCount, zrtpContext->supportedAuthTag);
addMandatoryCryptoTypesIfNeeded(algoType, zrtpContext->supportedAuthTag, &zrtpContext->ac);
break;
case ZRTP_KEYAGREEMENT_TYPE:
zrtpContext->kc = selectCommonAlgo(supportedTypes, supportedTypesCount, implementedTypes, implementedTypesCount, zrtpContext->supportedKeyAgreement);
addMandatoryCryptoTypesIfNeeded(algoType, zrtpContext->supportedKeyAgreement, &zrtpContext->kc);
break;
case ZRTP_SAS_TYPE:
zrtpContext->sc = selectCommonAlgo(supportedTypes, supportedTypesCount, implementedTypes, implementedTypesCount, zrtpContext->supportedSas);
addMandatoryCryptoTypesIfNeeded(algoType, zrtpContext->supportedSas, &zrtpContext->sc);
break;
}
}
......@@ -81,6 +81,38 @@ uint8_t bzrtpCrypto_getAvailableCryptoTypes(uint8_t algoType, uint8_t availableT
}
}
/** Return mandatory crypto functions. For now we have
*
* - Hash: HMAC-SHA256
* - CipherBlock: AES128
* - Auth Tag: HMAC-SHA132 and HMAC-SHA180
* - Key Agreement: DHM3k
* - Sas: base32
*/
uint8_t bzrtpCrypto_getMandatoryCryptoTypes(uint8_t algoType, uint8_t mandatoryTypes[7]) {
switch(algoType) {
case ZRTP_HASH_TYPE:
mandatoryTypes[0] = ZRTP_HASH_S256;
return 1;
case ZRTP_CIPHERBLOCK_TYPE:
mandatoryTypes[0] = ZRTP_CIPHER_AES1;
return 1;
case ZRTP_AUTHTAG_TYPE:
mandatoryTypes[0] = ZRTP_AUTHTAG_HS32;
mandatoryTypes[1] = ZRTP_AUTHTAG_HS80;
return 2;
case ZRTP_KEYAGREEMENT_TYPE:
mandatoryTypes[0] = ZRTP_KEYAGREEMENT_DH3k;
return 1;
case ZRTP_SAS_TYPE:
mandatoryTypes[0] = ZRTP_SAS_B32;
return 1;
default:
return 0;
}
}
/**
*
* @brief Structure to store all the contexts data needed for Random Number Generation
......
......@@ -469,6 +469,60 @@ uint8_t selectCommonAlgo(uint8_t masterArray[7], uint8_t masterArrayLength, uint
return commonLength;
}
/**
* @brief add mandatory crypto functions if they are not already included
* - Hash function
* - Cipher Block
* - Auth Tag
* - Key agreement
* - SAS
*
* @param[in] algoType mapped to defines, must be in [ZRTP_HASH_TYPE, ZRTP_CIPHERBLOCK_TYPE, ZRTP_AUTHTAG_TYPE, ZRTP_KEYAGREEMENT_TYPE or ZRTP_SAS_TYPE]
* @param[in/out] algoTypes mapped to uint8_t value of the 4 char strings giving the algo types as string according to rfc section 5.1.2 to 5.1.6
* @param[in/out] algoTypesCount number of algo types
*/
void addMandatoryCryptoTypesIfNeeded(uint8_t algoType, uint8_t algoTypes[7], uint8_t *algoTypesCount)
{
int i, j;
int algosBitmask[BITMASK_256_SIZE];
int missingBitmask[BITMASK_256_SIZE];
uint8_t mandatoryTypes[7];
const uint8_t mandatoryTypesCount = bzrtpCrypto_getMandatoryCryptoTypes(algoType, mandatoryTypes);
uint8_t missingTypesCount = mandatoryTypesCount;
BITMASK_256_SET_ZERO(missingBitmask);
BITMASK_256_SET_ZERO(algosBitmask);
for(i=0; i<mandatoryTypesCount; i++) {
BITMASK_256_SET(missingBitmask, mandatoryTypes[i]);
}
for (i=0,j=0; j<7 && (i<*algoTypesCount); i++) {
/*
* If we only have space left for missing crypto algos, only add them.
* Make sure we do not add elements twice.
*/
if ((j + missingTypesCount < 7 || BITMASK_256_CHECK(missingBitmask, algoTypes[i])) && !BITMASK_256_CHECK(algosBitmask, algoTypes[i])) {
BITMASK_256_SET(algosBitmask, algoTypes[i]);
algoTypes[j++] = algoTypes[i];
if (BITMASK_256_CHECK(missingBitmask, algoTypes[i])) {
BITMASK_256_UNSET(missingBitmask, algoTypes[i]);
missingTypesCount--;
}
}
}
/* add missing crypto types */
for (i=0; i<7 && missingTypesCount>0 && i<mandatoryTypesCount; i++) {
if (BITMASK_256_CHECK(missingBitmask, mandatoryTypes[i])) {
algoTypes[j++] = mandatoryTypes[i];
missingTypesCount--;
}
}
*algoTypesCount = j;
}
/*
* @brief Map the string description of algo type to an int defined in cryptoWrapper.h
*
......
......@@ -266,33 +266,11 @@ int bzrtp_packetParser(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpC
messageContent +=4;
}
/* supported algos may be empty which means that only mandatory algo are supported.
* In this case we must insert them in the message Data structure */
if (messageData->hc == 0) {
messageData->hc = 1;
messageData->supportedHash[0] = ZRTP_HASH_S256;
}
if (messageData->cc == 0) {
messageData->cc = 1;
messageData->supportedCipher[0] = ZRTP_CIPHER_AES1;
}
if (messageData->ac == 0) {
messageData->ac = 2;
messageData->supportedAuthTag[0] = ZRTP_AUTHTAG_HS32;
messageData->supportedAuthTag[1] = ZRTP_AUTHTAG_HS80;
}
if (messageData->kc == 0) {
messageData->kc = 1;
messageData->supportedKeyAgreement[0] = ZRTP_KEYAGREEMENT_DH3k;
}
if (messageData->sc == 0) {
messageData->sc = 1;
messageData->supportedSas[0] = ZRTP_SAS_B32;
}
addMandatoryCryptoTypesIfNeeded(ZRTP_HASH_TYPE, messageData->supportedHash, &messageData->hc);
addMandatoryCryptoTypesIfNeeded(ZRTP_CIPHERBLOCK_TYPE, messageData->supportedCipher, &messageData->cc);
addMandatoryCryptoTypesIfNeeded(ZRTP_AUTHTAG_TYPE, messageData->supportedAuthTag, &messageData->ac);
addMandatoryCryptoTypesIfNeeded(ZRTP_KEYAGREEMENT_TYPE, messageData->supportedKeyAgreement, &messageData->kc);
addMandatoryCryptoTypesIfNeeded(ZRTP_SAS_TYPE, messageData->supportedSas, &messageData->sc);
memcpy(messageData->MAC, messageContent, 8);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment