3 // ProtectedCloudStorage
5 // Copyright (c) 2014 Apple Inc. All rights reserved.
8 #include "keychain/SecureObjectSync/SOSInternal.h"
10 #include <AssertMacros.h>
12 #include <CommonCrypto/CommonRandomSPI.h>
13 #include <utilities/SecCFWrappers.h>
14 #include <utilities/SecCFError.h>
15 #include <utilities/SecBuffer.h>
16 #include <corecrypto/ccec.h>
19 #if 0 && defined(CCEC_RFC6637_DEBUG_KEYS)
20 #define DEBUGKEYS CCEC_RFC6637_DEBUG_KEYS
25 const char fingerprint
[20] = "fingerprint";
27 const uint8_t kAlgorithmID
= 1;
30 SOSCopyECWrappedData(ccec_pub_ctx_t ec_ctx
, CFDataRef data
, CFErrorRef
*error
)
32 CFMutableDataRef result
= NULL
;
33 CFMutableDataRef output
= NULL
;
37 require_quiet(SecRequirementError(data
!= NULL
, error
, CFSTR("data required for wrapping")), exit
);
38 require_quiet(SecRequirementError(ec_ctx
!= NULL
, error
, CFSTR("ec pub key required for wrapping")), exit
);
39 require_quiet(ec_ctx
!= NULL
, exit
);
41 outputLength
= ccec_rfc6637_wrap_key_size(ec_ctx
, CCEC_RFC6637_COMPACT_KEYS
| DEBUGKEYS
, CFDataGetLength(data
));
43 output
= CFDataCreateMutableWithScratch(NULL
, outputLength
);
44 require_quiet(SecAllocationError(output
, error
, CFSTR("%s CFData allocation failed"), __FUNCTION__
), exit
);
46 res
= ccec_rfc6637_wrap_key(ec_ctx
, CFDataGetMutableBytePtr(output
), CCEC_RFC6637_COMPACT_KEYS
| DEBUGKEYS
, kAlgorithmID
,
47 CFDataGetLength(data
), CFDataGetBytePtr(data
), &ccec_rfc6637_dh_curve_p256
,
48 &ccec_rfc6637_wrap_sha256_kek_aes128
, (const uint8_t *)fingerprint
,
49 ccDevRandomGetRngState());
50 require_noerr_action(res
, exit
, SOSErrorCreate(kSOSErrorProcessingFailure
, error
, NULL
, CFSTR("Wrap failed with %d"), res
));
52 CFTransferRetained(result
, output
);
55 CFReleaseNull(output
);
59 bool SOSPerformWithUnwrappedData(ccec_full_ctx_t ec_ctx
, CFDataRef data
, CFErrorRef
*error
,
60 void (^operation
)(size_t size
, uint8_t *buffer
))
62 __block
bool result
= false;
64 PerformWithBufferAndClear(CFDataGetLength(data
), ^(size_t size
, uint8_t *buffer
) {
65 size_t outputLength
= size
;
68 ec_result
= ccec_rfc6637_unwrap_key(ec_ctx
, &outputLength
, buffer
,
69 CCEC_RFC6637_COMPACT_KEYS
| DEBUGKEYS
, &alg
, &ccec_rfc6637_dh_curve_p256
,
70 &ccec_rfc6637_unwrap_sha256_kek_aes128
, (const uint8_t *)fingerprint
,
71 CFDataGetLength(data
), CFDataGetBytePtr(data
));
73 require_noerr_action(ec_result
, exit
, SOSErrorCreate(kSOSErrorProcessingFailure
, error
, NULL
, CFSTR("ccec_rfc6637_unwrap_key failed with %d"), ec_result
));
74 require_quiet(SecRequirementError(alg
== kAlgorithmID
, error
, CFSTR("Unexpected algorithm: %d"), (int)alg
), exit
);
76 operation(outputLength
, buffer
);
87 SOSCopyECUnwrappedData(ccec_full_ctx_t ec_ctx
, CFDataRef data
, CFErrorRef
*error
)
90 CFMutableDataRef result
= NULL
;
91 CFMutableDataRef output
= NULL
;
92 size_t outputLength
= CFDataGetLength(data
);
95 output
= CFDataCreateMutableWithScratch(NULL
, outputLength
);
96 require_quiet(SecAllocationError(output
, error
, CFSTR("%s CFData allocation failed"), __FUNCTION__
), exit
);
98 res
= ccec_rfc6637_unwrap_key(ec_ctx
, &outputLength
, CFDataGetMutableBytePtr(output
),
99 CCEC_RFC6637_COMPACT_KEYS
| DEBUGKEYS
, &alg
, &ccec_rfc6637_dh_curve_p256
,
100 &ccec_rfc6637_unwrap_sha256_kek_aes128
, (const uint8_t *)fingerprint
,
101 CFDataGetLength(data
), CFDataGetBytePtr(data
));
102 require_noerr_action(res
, exit
, SOSErrorCreate(kSOSErrorProcessingFailure
, error
, NULL
, CFSTR("Unwrap failed with %d"), res
));
103 require_quiet(SecRequirementError(alg
== kAlgorithmID
, error
, CFSTR("Unexpected algorithm: %d"), (int)alg
), exit
);
105 CFDataSetLength(output
, outputLength
);
107 CFTransferRetained(result
, output
);
110 CFReleaseNull(output
);