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>
43 // Random Number Generation
46 OSStatus
GetRandomBytesInLSBs(size_t bytesOfRandomness
, size_t n
, cc_unit
* place
)
48 OSStatus result
= errSecParam
;
49 require(bytesOfRandomness
* 8 <= ccn_bitsof_n(n
), fail
);
51 uint8_t randomBytes
[bytesOfRandomness
];
53 result
= SecRandomCopyBytes(kSecRandomDefault
, sizeof(randomBytes
), randomBytes
);
55 require_noerr(result
, fail
);
57 ccn_read_uint(n
, place
, sizeof(randomBytes
), randomBytes
);
59 bzero(randomBytes
, bytesOfRandomness
);
65 OSStatus
FillWithRandomBytes(size_t n
, cc_unit
* place
)
67 return GetRandomBytesInLSBs(ccn_sizeof(n
), n
, place
);
71 static const uint8_t kIVZero
[16] = { };
73 static void AES_CTR_Transform(size_t keySize
, const uint8_t* key
,
75 size_t howMuch
, const uint8_t* from
, uint8_t* to
)
77 const struct ccmode_ctr
* ctr_encrypt
= ccaes_ctr_crypt_mode();
78 ccctr_ctx_decl(ctr_encrypt
->size
, ctr_ctx
);
79 ctr_encrypt
->init(ctr_encrypt
, ctr_ctx
, keySize
, key
, iv
);
81 ctr_encrypt
->ctr(ctr_ctx
, howMuch
, from
, to
);
84 void AES_CTR_HighHalf_Transform(size_t keySize
, const uint8_t* key
,
86 size_t howMuch
, const uint8_t* from
, uint8_t* to
)
88 uint8_t iv
[16] = { highHalf
>> 56, highHalf
>> 48, highHalf
>> 40, highHalf
>> 32,
89 highHalf
>> 24, highHalf
>> 16, highHalf
>> 8 , highHalf
>> 0,
92 AES_CTR_Transform(keySize
, key
, iv
, howMuch
, from
, to
);
95 void AES_CTR_IV0_Transform(size_t keySize
, const uint8_t* key
,
96 size_t howMuch
, const uint8_t* from
, uint8_t* to
)
98 AES_CTR_Transform(keySize
, key
, kIVZero
, howMuch
, from
, to
);
106 static void HashMPIWithPrefix(uint8_t byte
, cc_size sN
, const cc_unit
* s
, uint8_t* buffer
)
108 CFMutableDataRef dataToHash
= CFDataCreateMutable(kCFAllocatorDefault
, 0);
109 CFDataAppendBytes(dataToHash
, &byte
, 1);
111 AppendMPI(dataToHash
, sN
, s
);
113 uint8_t *bytesToHash
= CFDataGetMutableBytePtr(dataToHash
);
114 CFIndex amountToHash
= CFDataGetLength(dataToHash
);
116 /* 64 bits cast: amountToHash is the size of an identity +1 , which is currently hardcoded and never more than 2^32 bytes */
117 assert((unsigned long)amountToHash
<UINT32_MAX
); /* Debug check, Correct as long as CFIndex is a signed long and CC_LONG is a uint32_t */
119 (void) CC_SHA256(bytesToHash
, (CC_LONG
)amountToHash
, buffer
);
121 bzero(bytesToHash
, (size_t)amountToHash
);
122 CFReleaseNull(dataToHash
);
125 void DeriveOTR256BitsFromS(KeyType whichKey
, cc_size sN
, const cc_unit
* s
, size_t keySize
, uint8_t* key
)
127 HashMPIWithPrefix(whichKey
, sN
, s
, key
);
130 void DeriveOTR128BitPairFromS(KeyType whichKey
, size_t sSize
, const cc_unit
* s
,
131 size_t firstKeySize
, uint8_t* firstKey
,
132 size_t secondKeySize
, uint8_t* secondKey
)
134 uint8_t hashBuffer
[CCSHA256_OUTPUT_SIZE
];
136 HashMPIWithPrefix(whichKey
, sSize
, s
, hashBuffer
);
139 firstKeySize
= firstKeySize
> CCSHA256_OUTPUT_SIZE
/2 ? CCSHA256_OUTPUT_SIZE
/2 : firstKeySize
;
140 memcpy(firstKey
, hashBuffer
, firstKeySize
);
143 secondKeySize
= secondKeySize
> CCSHA256_OUTPUT_SIZE
/2 ? CCSHA256_OUTPUT_SIZE
/2 : secondKeySize
;
144 memcpy(secondKey
, hashBuffer
, secondKeySize
);
147 bzero(hashBuffer
, CCSHA256_OUTPUT_SIZE
);
151 void DeriveOTR64BitsFromS(KeyType whichKey
, size_t sn
, const cc_unit
* s
,
152 size_t topKeySize
, uint8_t* topKey
)
154 uint8_t hashBuffer
[CCSHA256_OUTPUT_SIZE
];
156 HashMPIWithPrefix(whichKey
, sn
, s
, hashBuffer
);
158 topKeySize
= topKeySize
> CCSHA256_OUTPUT_SIZE
/2 ? CCSHA256_OUTPUT_SIZE
/2 : topKeySize
;
159 memcpy(topKey
, hashBuffer
, topKeySize
);
161 bzero(hashBuffer
, CCSHA256_OUTPUT_SIZE
);