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
47 static const uint8_t kIVZero
[16] = { };
49 static void AES_CTR_Transform(size_t keySize
, const uint8_t* key
,
51 size_t howMuch
, const uint8_t* from
, uint8_t* to
)
53 const struct ccmode_ctr
* ctr_encrypt
= ccaes_ctr_crypt_mode();
54 ccctr_ctx_decl(ctr_encrypt
->size
, ctr_ctx
);
55 ctr_encrypt
->init(ctr_encrypt
, ctr_ctx
, keySize
, key
, iv
);
57 ctr_encrypt
->ctr(ctr_ctx
, howMuch
, from
, to
);
60 void AES_CTR_HighHalf_Transform(size_t keySize
, const uint8_t* key
,
62 size_t howMuch
, const uint8_t* from
, uint8_t* to
)
64 uint8_t iv
[16] = { highHalf
>> 56, highHalf
>> 48, highHalf
>> 40, highHalf
>> 32,
65 highHalf
>> 24, highHalf
>> 16, highHalf
>> 8 , highHalf
>> 0,
68 AES_CTR_Transform(keySize
, key
, iv
, howMuch
, from
, to
);
71 void AES_CTR_IV0_Transform(size_t keySize
, const uint8_t* key
,
72 size_t howMuch
, const uint8_t* from
, uint8_t* to
)
74 AES_CTR_Transform(keySize
, key
, kIVZero
, howMuch
, from
, to
);
82 static void HashMPIWithPrefix(uint8_t byte
, cc_size sN
, const cc_unit
* s
, uint8_t* buffer
)
84 CFMutableDataRef dataToHash
= CFDataCreateMutable(kCFAllocatorDefault
, 0);
85 CFDataAppendBytes(dataToHash
, &byte
, 1);
87 AppendMPI(dataToHash
, sN
, s
);
89 uint8_t *bytesToHash
= CFDataGetMutableBytePtr(dataToHash
);
90 CFIndex amountToHash
= CFDataGetLength(dataToHash
);
92 /* 64 bits cast: amountToHash is the size of an identity +1 , which is currently hardcoded and never more than 2^32 bytes */
93 assert((unsigned long)amountToHash
<UINT32_MAX
); /* Debug check, Correct as long as CFIndex is a signed long and CC_LONG is a uint32_t */
95 (void) CC_SHA256(bytesToHash
, (CC_LONG
)amountToHash
, buffer
);
97 bzero(bytesToHash
, (size_t)amountToHash
);
98 CFReleaseNull(dataToHash
);
101 void DeriveOTR256BitsFromS(OTRKeyType whichKey
, cc_size sN
, const cc_unit
* s
, size_t keySize
, uint8_t* key
)
103 HashMPIWithPrefix(whichKey
, sN
, s
, key
);
106 void DeriveOTR128BitPairFromS(OTRKeyType whichKey
, size_t sSize
, const cc_unit
* s
,
107 size_t firstKeySize
, uint8_t* firstKey
,
108 size_t secondKeySize
, uint8_t* secondKey
)
110 uint8_t hashBuffer
[CCSHA256_OUTPUT_SIZE
];
112 HashMPIWithPrefix(whichKey
, sSize
, s
, hashBuffer
);
115 firstKeySize
= firstKeySize
> CCSHA256_OUTPUT_SIZE
/2 ? CCSHA256_OUTPUT_SIZE
/2 : firstKeySize
;
116 memcpy(firstKey
, hashBuffer
, firstKeySize
);
119 secondKeySize
= secondKeySize
> CCSHA256_OUTPUT_SIZE
/2 ? CCSHA256_OUTPUT_SIZE
/2 : secondKeySize
;
120 memcpy(secondKey
, hashBuffer
, secondKeySize
);
123 bzero(hashBuffer
, CCSHA256_OUTPUT_SIZE
);
127 void DeriveOTR64BitsFromS(OTRKeyType whichKey
, size_t sn
, const cc_unit
* s
,
128 size_t topKeySize
, uint8_t* topKey
)
130 uint8_t hashBuffer
[CCSHA256_OUTPUT_SIZE
];
132 HashMPIWithPrefix(whichKey
, sn
, s
, hashBuffer
);
134 topKeySize
= topKeySize
> CCSHA256_OUTPUT_SIZE
/2 ? CCSHA256_OUTPUT_SIZE
/2 : topKeySize
;
135 memcpy(topKey
, hashBuffer
, topKeySize
);
137 bzero(hashBuffer
, CCSHA256_OUTPUT_SIZE
);