]> git.saurik.com Git - apple/security.git/blob - OSX/sec/ProjectHeaders/Security/SecureObjectSync/SOSECWrapUnwrap.c
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / sec / ProjectHeaders / Security / SecureObjectSync / SOSECWrapUnwrap.c
1 //
2 // cc_CFData.c
3 // ProtectedCloudStorage
4 //
5 // Copyright (c) 2014 Apple Inc. All rights reserved.
6 //
7
8 #include "SOSInternal.h"
9
10 #include <AssertMacros.h>
11
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>
17
18
19 #if 0 && defined(CCEC_RFC6637_DEBUG_KEYS)
20 #define DEBUGKEYS CCEC_RFC6637_DEBUG_KEYS
21 #else
22 #define DEBUGKEYS 0
23 #endif
24
25 const char fingerprint[20] = "fingerprint";
26
27 const uint8_t kAlgorithmID = 1;
28
29 CFMutableDataRef
30 SOSCopyECWrappedData(ccec_pub_ctx *ec_ctx, CFDataRef data, CFErrorRef *error)
31 {
32 CFMutableDataRef result = NULL;
33 CFMutableDataRef output = NULL;
34 size_t outputLength;
35 int res;
36
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
40 outputLength = ccec_rfc6637_wrap_key_size(ec_ctx, CCEC_RFC6637_COMPACT_KEYS | DEBUGKEYS, CFDataGetLength(data));
41
42 output = CFDataCreateMutableWithScratch(NULL, outputLength);
43 require_quiet(SecAllocationError(output, error, CFSTR("%s CFData allocation failed"), __FUNCTION__), exit);
44
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));
50
51 CFTransferRetained(result, output);
52
53 exit:
54 CFReleaseNull(output);
55 return result;
56 }
57
58 bool SOSPerformWithUnwrappedData(ccec_full_ctx_t ec_ctx, CFDataRef data, CFErrorRef *error,
59 void (^operation)(size_t size, uint8_t *buffer))
60 {
61 __block bool result = false;
62
63 PerformWithBufferAndClear(CFDataGetLength(data), ^(size_t size, uint8_t *buffer) {
64 size_t outputLength = size;
65 int ec_result;
66 uint8_t alg;
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));
71
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);
74
75 operation(outputLength, buffer);
76
77 result = true;
78 exit:
79 ;
80 });
81
82 return result;
83 }
84
85 CFMutableDataRef
86 SOSCopyECUnwrappedData(ccec_full_ctx_t ec_ctx, CFDataRef data, CFErrorRef *error)
87 {
88 uint8_t alg;
89 CFMutableDataRef result = NULL;
90 CFMutableDataRef output = NULL;
91 size_t outputLength = CFDataGetLength(data);
92 int res;
93
94 output = CFDataCreateMutableWithScratch(NULL, outputLength);
95 require_quiet(SecAllocationError(output, error, CFSTR("%s CFData allocation failed"), __FUNCTION__), exit);
96
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);
103
104 CFDataSetLength(output, outputLength);
105
106 CFTransferRetained(result, output);
107
108 exit:
109 CFReleaseNull(output);
110 return result;
111 }