>From 67e060acfd4437069905662674a2791c6ef017cb Mon Sep 17 00:00:00 2001 From: Ben Sartor Date: Sun, 25 Jan 2015 01:02:52 +0100 Subject: [PATCH 13/15] make sure mandatory algorithm types are always supported --- include/cryptoUtils.h | 14 +++++++++++++ include/cryptoWrapper.h | 15 ++++++++++++++ src/bzrtp.c | 5 +++++ src/cryptoPolarssl.c | 32 +++++++++++++++++++++++++++++ src/cryptoUtils.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ src/packetParser.c | 32 +++++------------------------ 6 files changed, 125 insertions(+), 27 deletions(-) diff --git a/include/cryptoUtils.h b/include/cryptoUtils.h index 34b168c..85bd782 100644 --- a/include/cryptoUtils.h +++ b/include/cryptoUtils.h @@ -138,6 +138,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 * * @param[in] algoType A 4 chars string containing the algo type as listed in rfc sections 5.1.2 to 5.1.6 diff --git a/include/cryptoWrapper.h b/include/cryptoWrapper.h index 2bf421d..f32f548 100644 --- a/include/cryptoWrapper.h +++ b/include/cryptoWrapper.h @@ -51,6 +51,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 * actually just holds a pointer to the crypto module implementation context diff --git a/src/bzrtp.c b/src/bzrtp.c index 21be500..ef78e6a 100644 --- a/src/bzrtp.c +++ b/src/bzrtp.c @@ -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; } } diff --git a/src/cryptoPolarssl.c b/src/cryptoPolarssl.c index 5f1826a..f19d6ca 100644 --- a/src/cryptoPolarssl.c +++ b/src/cryptoPolarssl.c @@ -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 diff --git a/src/cryptoUtils.c b/src/cryptoUtils.c index 19d06a3..6034245 100644 --- a/src/cryptoUtils.c +++ b/src/cryptoUtils.c @@ -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; i0 && ihc == 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); -- 2.1.4