]>
Commit | Line | Data |
---|---|---|
5c19dc3a A |
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); | |
fa7225c8 | 39 | require_quiet(ec_ctx != NULL, exit); |
5c19dc3a A |
40 | |
41 | outputLength = ccec_rfc6637_wrap_key_size(ec_ctx, CCEC_RFC6637_COMPACT_KEYS | DEBUGKEYS, CFDataGetLength(data)); | |
42 | ||
43 | output = CFDataCreateMutableWithScratch(NULL, outputLength); | |
44 | require_quiet(SecAllocationError(output, error, CFSTR("%s CFData allocation failed"), __FUNCTION__), exit); | |
45 | ||
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)); | |
51 | ||
52 | CFTransferRetained(result, output); | |
53 | ||
54 | exit: | |
55 | CFReleaseNull(output); | |
56 | return result; | |
57 | } | |
58 | ||
59 | bool SOSPerformWithUnwrappedData(ccec_full_ctx_t ec_ctx, CFDataRef data, CFErrorRef *error, | |
60 | void (^operation)(size_t size, uint8_t *buffer)) | |
61 | { | |
62 | __block bool result = false; | |
63 | ||
64 | PerformWithBufferAndClear(CFDataGetLength(data), ^(size_t size, uint8_t *buffer) { | |
65 | size_t outputLength = size; | |
66 | int ec_result; | |
67 | uint8_t alg; | |
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)); | |
72 | ||
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); | |
75 | ||
76 | operation(outputLength, buffer); | |
77 | ||
78 | result = true; | |
79 | exit: | |
80 | ; | |
81 | }); | |
82 | ||
83 | return result; | |
84 | } | |
85 | ||
86 | CFMutableDataRef | |
87 | SOSCopyECUnwrappedData(ccec_full_ctx_t ec_ctx, CFDataRef data, CFErrorRef *error) | |
88 | { | |
89 | uint8_t alg; | |
90 | CFMutableDataRef result = NULL; | |
91 | CFMutableDataRef output = NULL; | |
92 | size_t outputLength = CFDataGetLength(data); | |
93 | int res; | |
94 | ||
95 | output = CFDataCreateMutableWithScratch(NULL, outputLength); | |
96 | require_quiet(SecAllocationError(output, error, CFSTR("%s CFData allocation failed"), __FUNCTION__), exit); | |
97 | ||
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); | |
104 | ||
105 | CFDataSetLength(output, outputLength); | |
106 | ||
107 | CFTransferRetained(result, output); | |
108 | ||
109 | exit: | |
110 | CFReleaseNull(output); | |
111 | return result; | |
112 | } |