2 * Copyright (c) 2011-2012,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 #include "SecOTRMath.h"
27 #include "SecOTRPacketData.h"
29 #include <utilities/SecCFWrappers.h>
30 #include <AssertMacros.h>
34 #include <Security/SecRandom.h>
36 #include <corecrypto/ccsha2.h>
37 #include <corecrypto/cczp.h>
38 #include <corecrypto/ccdh_gp.h>
42 void OTRExponentiate(cc_unit
* res
, const cc_unit
* base
, const cc_unit
* exponent
)
44 ccdh_const_gp_t gp
= ccdh_gp_rfc3526group05();
45 cczp_power(gp
.zp
, res
, base
, exponent
);
48 void OTRGroupExponentiate(cc_unit
* res
, const cc_unit
* exponent
)
50 OTRExponentiate(res
, ccdh_gp_g(ccdh_gp_rfc3526group05()) , exponent
);
54 // Random Number Generation
57 OSStatus
GetRandomBytesInLSBs(size_t bytesOfRandomness
, size_t n
, cc_unit
* place
)
59 OSStatus result
= errSecParam
;
60 require(bytesOfRandomness
* 8 <= ccn_bitsof_n(n
), fail
);
62 uint8_t randomBytes
[bytesOfRandomness
];
64 result
= SecRandomCopyBytes(kSecRandomDefault
, sizeof(randomBytes
), randomBytes
);
66 require_noerr(result
, fail
);
68 ccn_read_uint(n
, place
, sizeof(randomBytes
), randomBytes
);
70 bzero(randomBytes
, bytesOfRandomness
);
76 OSStatus
FillWithRandomBytes(size_t n
, cc_unit
* place
)
78 return GetRandomBytesInLSBs(ccn_sizeof(n
), n
, place
);
82 static const uint8_t kIVZero
[16] = { };
84 static void AES_CTR_Transform(size_t keySize
, const uint8_t* key
,
86 size_t howMuch
, const uint8_t* from
, uint8_t* to
)
88 const struct ccmode_ctr
* ctr_encrypt
= ccaes_ctr_crypt_mode();
89 ccctr_ctx_decl(ctr_encrypt
->size
, ctr_ctx
);
90 ctr_encrypt
->init(ctr_encrypt
, ctr_ctx
, keySize
, key
, iv
);
92 ctr_encrypt
->ctr(ctr_ctx
, howMuch
, from
, to
);
95 void AES_CTR_HighHalf_Transform(size_t keySize
, const uint8_t* key
,
97 size_t howMuch
, const uint8_t* from
, uint8_t* to
)
99 uint8_t iv
[16] = { highHalf
>> 56, highHalf
>> 48, highHalf
>> 40, highHalf
>> 32,
100 highHalf
>> 24, highHalf
>> 16, highHalf
>> 8 , highHalf
>> 0,
103 AES_CTR_Transform(keySize
, key
, iv
, howMuch
, from
, to
);
106 void AES_CTR_IV0_Transform(size_t keySize
, const uint8_t* key
,
107 size_t howMuch
, const uint8_t* from
, uint8_t* to
)
109 AES_CTR_Transform(keySize
, key
, kIVZero
, howMuch
, from
, to
);
117 static void HashMPIWithPrefix(uint8_t byte
, cc_size sN
, const cc_unit
* s
, uint8_t* buffer
)
119 CFMutableDataRef dataToHash
= CFDataCreateMutable(kCFAllocatorDefault
, 0);
120 CFDataAppendBytes(dataToHash
, &byte
, 1);
122 AppendMPI(dataToHash
, sN
, s
);
124 uint8_t *bytesToHash
= CFDataGetMutableBytePtr(dataToHash
);
125 CFIndex amountToHash
= CFDataGetLength(dataToHash
);
127 /* 64 bits cast: amountToHash is the size of an identity +1 , which is currently hardcoded and never more than 2^32 bytes */
128 assert((unsigned long)amountToHash
<UINT32_MAX
); /* Debug check, Correct as long as CFIndex is a signed long and CC_LONG is a uint32_t */
130 (void) CC_SHA256(bytesToHash
, (CC_LONG
)amountToHash
, buffer
);
132 bzero(bytesToHash
, (size_t)amountToHash
);
133 CFReleaseNull(dataToHash
);
136 void DeriveOTR256BitsFromS(KeyType whichKey
, cc_size sN
, const cc_unit
* s
, size_t keySize
, uint8_t* key
)
138 HashMPIWithPrefix(whichKey
, sN
, s
, key
);
141 void DeriveOTR128BitPairFromS(KeyType whichKey
, size_t sSize
, const cc_unit
* s
,
142 size_t firstKeySize
, uint8_t* firstKey
,
143 size_t secondKeySize
, uint8_t* secondKey
)
145 uint8_t hashBuffer
[CCSHA256_OUTPUT_SIZE
];
147 HashMPIWithPrefix(whichKey
, sSize
, s
, hashBuffer
);
150 firstKeySize
= firstKeySize
> CCSHA256_OUTPUT_SIZE
/2 ? CCSHA256_OUTPUT_SIZE
/2 : firstKeySize
;
151 memcpy(firstKey
, hashBuffer
, firstKeySize
);
154 secondKeySize
= secondKeySize
> CCSHA256_OUTPUT_SIZE
/2 ? CCSHA256_OUTPUT_SIZE
/2 : secondKeySize
;
155 memcpy(secondKey
, hashBuffer
, secondKeySize
);
158 bzero(hashBuffer
, CCSHA256_OUTPUT_SIZE
);
162 void DeriveOTR64BitsFromS(KeyType whichKey
, size_t sn
, const cc_unit
* s
,
163 size_t topKeySize
, uint8_t* topKey
)
165 uint8_t hashBuffer
[CCSHA256_OUTPUT_SIZE
];
167 HashMPIWithPrefix(whichKey
, sn
, s
, hashBuffer
);
169 topKeySize
= topKeySize
> CCSHA256_OUTPUT_SIZE
/2 ? CCSHA256_OUTPUT_SIZE
/2 : topKeySize
;
170 memcpy(topKey
, hashBuffer
, topKeySize
);
172 bzero(hashBuffer
, CCSHA256_OUTPUT_SIZE
);