X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5dd5f9ec28f304ca377c42fd7f711d6cf12b90e1..5c19dc3ae3bd8e40a9c028b0deddd50ff337692c:/OSX/sec/Security/SecOTRMath.c diff --git a/OSX/sec/Security/SecOTRMath.c b/OSX/sec/Security/SecOTRMath.c new file mode 100644 index 00000000..32323637 --- /dev/null +++ b/OSX/sec/Security/SecOTRMath.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2011-2012,2014 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +#include "SecOTRMath.h" + +#include "SecOTRPacketData.h" + +#include +#include + +#include + +#include + +#include +#include +#include + +#include + +void OTRExponentiate(cc_unit* res, const cc_unit* base, const cc_unit* exponent) +{ + ccdh_const_gp_t gp = ccdh_gp_rfc3526group05(); + cczp_power(gp.zp, res, base, exponent); +} + +void OTRGroupExponentiate(cc_unit* res, const cc_unit* exponent) +{ + OTRExponentiate(res, ccdh_gp_g(ccdh_gp_rfc3526group05()) , exponent); +} + +// +// Random Number Generation +// + +OSStatus GetRandomBytesInLSBs(size_t bytesOfRandomness, size_t n, cc_unit* place) +{ + OSStatus result = errSecParam; + require(bytesOfRandomness * 8 <= ccn_bitsof_n(n), fail); + { + uint8_t randomBytes[bytesOfRandomness]; + + result = SecRandomCopyBytes(kSecRandomDefault, sizeof(randomBytes), randomBytes); + + require_noerr(result, fail); + + ccn_read_uint(n, place, sizeof(randomBytes), randomBytes); + + bzero(randomBytes, bytesOfRandomness); + } +fail: + return result; +} + +OSStatus FillWithRandomBytes(size_t n, cc_unit* place) +{ + return GetRandomBytesInLSBs(ccn_sizeof(n), n, place); +} + + +static const uint8_t kIVZero[16] = { }; + +static void AES_CTR_Transform(size_t keySize, const uint8_t* key, + const uint8_t iv[16], + size_t howMuch, const uint8_t* from, uint8_t* to) +{ + const struct ccmode_ctr* ctr_encrypt = ccaes_ctr_crypt_mode(); + ccctr_ctx_decl(ctr_encrypt->size, ctr_ctx); + ctr_encrypt->init(ctr_encrypt, ctr_ctx, keySize, key, iv); + + ctr_encrypt->ctr(ctr_ctx, howMuch, from, to); +} + +void AES_CTR_HighHalf_Transform(size_t keySize, const uint8_t* key, + uint64_t highHalf, + size_t howMuch, const uint8_t* from, uint8_t* to) +{ + uint8_t iv[16] = { highHalf >> 56, highHalf >> 48, highHalf >> 40, highHalf >> 32, + highHalf >> 24, highHalf >> 16, highHalf >> 8 , highHalf >> 0, + 0, 0, 0, 0, + 0, 0, 0, 0 }; + AES_CTR_Transform(keySize, key, iv, howMuch, from, to); +} + +void AES_CTR_IV0_Transform(size_t keySize, const uint8_t* key, + size_t howMuch, const uint8_t* from, uint8_t* to) +{ + AES_CTR_Transform(keySize, key, kIVZero, howMuch, from, to); +} + + +// +// Key Derivation +// + +static void HashMPIWithPrefix(uint8_t byte, cc_size sN, const cc_unit* s, uint8_t* buffer) +{ + CFMutableDataRef dataToHash = CFDataCreateMutable(kCFAllocatorDefault, 0); + CFDataAppendBytes(dataToHash, &byte, 1); + + AppendMPI(dataToHash, sN, s); + + uint8_t *bytesToHash = CFDataGetMutableBytePtr(dataToHash); + CFIndex amountToHash = CFDataGetLength(dataToHash); + + /* 64 bits cast: amountToHash is the size of an identity +1 , which is currently hardcoded and never more than 2^32 bytes */ + assert((unsigned long)amountToHash CCSHA256_OUTPUT_SIZE/2 ? CCSHA256_OUTPUT_SIZE/2 : firstKeySize; + memcpy(firstKey, hashBuffer, firstKeySize); + } + if (secondKey) { + secondKeySize = secondKeySize > CCSHA256_OUTPUT_SIZE/2 ? CCSHA256_OUTPUT_SIZE/2 : secondKeySize; + memcpy(secondKey, hashBuffer, secondKeySize); + } + + bzero(hashBuffer, CCSHA256_OUTPUT_SIZE); + +} + +void DeriveOTR64BitsFromS(KeyType whichKey, size_t sn, const cc_unit* s, + size_t topKeySize, uint8_t* topKey) +{ + uint8_t hashBuffer[CCSHA256_OUTPUT_SIZE]; + + HashMPIWithPrefix(whichKey, sn, s, hashBuffer); + + topKeySize = topKeySize > CCSHA256_OUTPUT_SIZE/2 ? CCSHA256_OUTPUT_SIZE/2 : topKeySize; + memcpy(topKey, hashBuffer, topKeySize); + + bzero(hashBuffer, CCSHA256_OUTPUT_SIZE); +} +