3 // ProtectedCloudStorage
5 // Copyright (c) 2014 Apple Inc. All rights reserved.
8 #include "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
*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
);
40 outputLength
= ccec_rfc6637_wrap_key_size(ec_ctx
, CCEC_RFC6637_COMPACT_KEYS
| DEBUGKEYS
, CFDataGetLength(data
));
42 output
= CFDataCreateMutableWithScratch(NULL
, outputLength
);
43 require_quiet(SecAllocationError(output
, error
, CFSTR("%s CFData allocation failed"), __FUNCTION__
), exit
);
45 res
= ccec_rfc6637_wrap_key(ec_ctx
, CFDataGetMutableBytePtr(output
), CCEC_RFC6637_COMPACT_KEYS
| DEBUGKEYS
, kAlgorithmID
,
46 CFDataGetLength(data
), CFDataGetBytePtr(data
), &ccec_rfc6637_dh_curve_p256
,
47 &ccec_rfc6637_wrap_sha256_kek_aes128
, (const uint8_t *)fingerprint
,
48 ccDevRandomGetRngState());
49 require_noerr_action(res
, exit
, SOSErrorCreate(kSOSErrorProcessingFailure
, error
, NULL
, CFSTR("Wrap failed with %d"), res
));
51 CFTransferRetained(result
, output
);
54 CFReleaseNull(output
);
58 bool SOSPerformWithUnwrappedData(ccec_full_ctx_t ec_ctx
, CFDataRef data
, CFErrorRef
*error
,
59 void (^operation
)(size_t size
, uint8_t *buffer
))
61 __block
bool result
= false;
63 PerformWithBufferAndClear(CFDataGetLength(data
), ^(size_t size
, uint8_t *buffer
) {
64 size_t outputLength
= size
;
67 ec_result
= ccec_rfc6637_unwrap_key(ec_ctx
, &outputLength
, buffer
,
68 CCEC_RFC6637_COMPACT_KEYS
| DEBUGKEYS
, &alg
, &ccec_rfc6637_dh_curve_p256
,
69 &ccec_rfc6637_unwrap_sha256_kek_aes128
, (const uint8_t *)fingerprint
,
70 CFDataGetLength(data
), CFDataGetBytePtr(data
));
72 require_noerr_action(ec_result
, exit
, SOSErrorCreate(kSOSErrorProcessingFailure
, error
, NULL
, CFSTR("ccec_rfc6637_unwrap_key failed with %d"), ec_result
));
73 require_quiet(SecRequirementError(alg
== kAlgorithmID
, error
, CFSTR("Unexpected algorithm: %d"), (int)alg
), exit
);
75 operation(outputLength
, buffer
);
86 SOSCopyECUnwrappedData(ccec_full_ctx_t ec_ctx
, CFDataRef data
, CFErrorRef
*error
)
89 CFMutableDataRef result
= NULL
;
90 CFMutableDataRef output
= NULL
;
91 size_t outputLength
= CFDataGetLength(data
);
94 output
= CFDataCreateMutableWithScratch(NULL
, outputLength
);
95 require_quiet(SecAllocationError(output
, error
, CFSTR("%s CFData allocation failed"), __FUNCTION__
), exit
);
97 res
= ccec_rfc6637_unwrap_key(ec_ctx
, &outputLength
, CFDataGetMutableBytePtr(output
),
98 CCEC_RFC6637_COMPACT_KEYS
| DEBUGKEYS
, &alg
, &ccec_rfc6637_dh_curve_p256
,
99 &ccec_rfc6637_unwrap_sha256_kek_aes128
, (const uint8_t *)fingerprint
,
100 CFDataGetLength(data
), CFDataGetBytePtr(data
));
101 require_noerr_action(res
, exit
, SOSErrorCreate(kSOSErrorProcessingFailure
, error
, NULL
, CFSTR("Unwrap failed with %d"), res
));
102 require_quiet(SecRequirementError(alg
== kAlgorithmID
, error
, CFSTR("Unexpected algorithm: %d"), (int)alg
), exit
);
104 CFDataSetLength(output
, outputLength
);
106 CFTransferRetained(result
, output
);
109 CFReleaseNull(output
);